home *** CD-ROM | disk | FTP | other *** search
- {
- $Id: symtable.pas,v 1.1.1.1.2.4 1998/08/13 17:41:28 florian Exp $
- Copyright (c) 1993-98 by Florian Klaempfl, Pierre Muller
-
- This unit handles the symbol tables
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ****************************************************************************
- }
- unit symtable;
-
- interface
-
- uses
- objects,cobjects,verbose,systems,globals,strings,aasm,files,link
- {$ifdef i386}
- ,i386
- {$endif}
- {$ifdef m68k}
- ,m68k
- {$endif}
- {$ifdef alpha}
- ,alpha
- {$endif}
- {$ifdef GDB}
- ,gdb
- {$endif}
- {$ifdef UseBrowser}
- ,browser
- {$endif UseBrowser}
- ;
-
- const
- {$ifdef FPC}
- ppubufsize=32768;
- {$ELSE}
- {$IFDEF USEOVERLAY}
- ppubufsize=512;
- {$ELSE}
- ppubufsize=4096;
- {$ENDIF}
- {$ENDIF}
- { possible types of symtables }
- { changed in two field
- one for the lexlevel
- and one for the symtabletype (PM)
- localsymtable = $8000;
- parasymtable = $4000;
- locallevel = $3fff;
- withsymtable = 1;
- staticsymtable = 2;
- globalsymtable = 3;
- unitsymtable = 4;
- objectsymtable = 5;
- recordsymtable = 6;
- macrosymtable = 7;
- localsymtable = 8;
- parasymtable = 9;}
-
- type
- tsymtabletype = (withsymtable,staticsymtable,
- globalsymtable,unitsymtable,
- objectsymtable,recordsymtable,
- macrosymtable,localsymtable,
- parasymtable);
-
- const
- { different options }
- sp_public = 0;
- sp_forwarddef = 1;
- sp_protected = 2;
- sp_private = 4;
- sp_static = 8;
-
- type
- symprop = byte;
-
- const
- poexceptions = $1; {????}
- povirtualmethod = $2; {Procedure is a virtual method.}
- poclearstack = $4; {Use IBM flat calling convention. (Used
- by GCC.)}
- poconstructor = $8; {Procedure is a constructor.}
- podestructor = $10; {Procedure is a constructor.}
- pointernproc = $20; {????}
- poexports = $40; {Procedure is exported.}
- poiocheck = $80; {IO checking should be done after
- a call to the procedure.}
- poabstractmethod = $100; {Procedure is an abstract method.}
- pointerrupt = $200; {Procedure is an interrupt handler.}
- poinline = $400; {Procedure is an assembler macro.}
- poassembler = $800; {Procedure is written in assembler.}
- pooperator = $1000; {Procedure defines an operator.}
- poexternal = $2000; {Procedure is external. It is either in
- a separate object file, or it is stored
- in a dynamic link library. This is
- determined by the fields of Tprocsym.}
- poleftright = $4000; {Push parameters from left to right.
- Currently unsupported.}
- poproginit = $8000; {Program initialisation.}
- { cdecl is the same as poclearstack }
- pocdecl = poclearstack;
- postaticmethod = $10000;
- pooverridingmethod=$20000;
- poclassmethod = $40000;
- pounitinit = $80000; {unit initialisation.}
- popalmossyscall = $100000;
-
- hasharraysize = 97;
-
- { last operator which can be overloaded }
- last_overloaded = ASSIGNMENT;
-
- const
- { options for objects and classes }
- oois_abstract = $1;
- oois_class = $2;
- oo_hasvirtual = $4;
- oo_hasprivate = $8;
- oo_hasprotected = $10;
- oo_isforward = $20;
-
- { options for properties }
- ppo_indexed = $1;
- ppo_defaultproperty = $2;
-
- type
- pword = ^word;
-
- { "forward" pointer }
- pformaldef = ^tformaldef;
- pfiledef = ^tfiledef;
- pobjectdef = ^tobjectdef;
- precdef = ^trecdef;
- parraydef = ^tarraydef;
- ppointerdef = ^tpointerdef;
- pstringdef = ^tstringdef;
- penumdef = ^tenumdef;
- porddef = ^torddef;
- pfloatdef = ^tfloatdef;
- pprocdef = ^tprocdef;
- perrordef = ^terrordef;
- psetdef = ^tsetdef;
- pclassrefdef = ^tclassrefdef;
-
- psymtable = ^tsymtable;
- punitsymtable = ^tunitsymtable;
-
- pdef = ^tdef;
- pprocvardef = ^tprocvardef;
- pabstractprocdef = ^tabstractprocdef;
- psym = ^tsym;
- plabelsym = ^tlabelsym;
- ppropertysym = ^tpropertysym;
-
- { base types }
- tbasetype = (uauto,u8bit,s32bit,uvoid,bool8bit,uchar,
- s8bit,s16bit,u16bit,u32bit);
-
- { sextreal is dependant on the cpu, s64bit is also }
- { dependant on the size (tp = 80bit for both) }
- { The EXTENDED format exists on the motorola FPU }
- { but it uses 96 bits instead of 80, with some }
- { unused bits within the number itself! Pretty }
- { complicated to support, so no support for the }
- { moment. }
- { s64 bit is considered as a real because all }
- { calculations are done by the fpu. }
- tfloattype = (f32bit,s32real,s64real,s80real,s64bit,f16bit);
-
- { possible types for symtable entries }
- tsymtyp = (abstractsym,varsym,typesym,procsym,unitsym,programsym,
- constsym,enumsym,typedconstsym,errorsym,syssym,
- labelsym,absolutesym,propertysym,funcretsym);
-
- { added a new field for tdefcoll for firstcalln }
- { convertable is if is_convertable returns true
- equal is if is_equal returns true
- exact is if the def is the same excatly }
-
- targconvtyp = (act_convertable,act_equal,act_exact);
-
- tvarspez = (vs_value,vs_const,vs_var);
-
- pdefcoll = ^tdefcoll;
-
- tdefcoll = record
- data : pdef;
- next : pdefcoll;
- paratyp : tvarspez;
- argconvtyp : targconvtyp;
- end;
-
- { this object is the base for all symbol objects }
- tsym = object
- typ : tsymtyp;
- _name : pchar;
- left : psym;
- right : psym;
- speedvalue : longint;
- properties : symprop;
- owner : psymtable;
- {$ifdef UseBrowser}
- lastref,defref,lastwritten : pref;
- refcount : longint;
- indexnb : word; { this limit the number of symbols to
- 65000 per unit, should not be a big problem !! }
- {$endif UseBrowser}
- {$ifdef GDB}
- isstabwritten : boolean;
- {$endif GDB}
- {$ifdef tp}
- line_no : word;
- {$else}
- line_no : longint;
- {$endif}
- constructor init(const n : string);
- constructor load;
- destructor done;virtual;
- procedure write;virtual;
- procedure deref;virtual;
- function name : string;
- function mangledname : string;virtual;
- procedure setname(const s : string);
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- {$ifdef UseBrowser}
- procedure load_references; virtual;
- procedure write_references; virtual;
- procedure write_external_references;
- procedure write_ref_to_file(var f : text);
- {$endif UseBrowser}
- end;
-
- tlabelsym = object(tsym)
- number : plabel;
- defined : boolean;
- constructor init(const n : string; l : plabel);
- destructor done;virtual;
- function mangledname : string;virtual;
- procedure write;virtual;
- end;
-
- punitsym = ^tunitsym;
-
- tunitsym = object(tsym)
- unitsymtable : punitsymtable;
- prevsym : punitsym;
- refs : longint;
- constructor init(const n : string;ref : punitsymtable);
- destructor done;virtual;
- procedure write;virtual;
- {$ifdef GDB}
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- pmacrosym = ^tmacrosym;
-
- tmacrosym = object(tsym)
- defined : boolean;
- buftext : pchar;
- buflen : longint;
- { macros aren't written to PPU files ! }
- constructor init(const n : string);
- destructor done;virtual;
- end;
-
- perrorsym = ^terrorsym;
-
- terrorsym = object(tsym)
- constructor init;
- end;
-
- pprocsym = ^tprocsym;
-
- tprocsym = object(tsym)
- definition : pprocdef;
- {$ifdef CHAINPROCSYMS}
- nextprocsym : pprocsym;
- {$endif CHAINPROCSYMS}
- {$ifdef GDB}
- is_global : boolean;{necessary for stab}
- {$endif GDB}
- constructor init(const n : string);
- constructor load;
- destructor done;virtual;
- function mangledname : string;virtual;
- { tests, if all procedures definitions are defined and not }
- { only forward }
- procedure check_forward;
- procedure write;virtual;
- procedure deref;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- ptypesym = ^ttypesym;
-
- ttypesym = object(tsym)
- definition : pdef;
- forwardpointer : ppointerdef;
- {$ifdef GDB}
- isusedinstab : boolean;
- {$endif GDB}
- constructor init(const n : string;d : pdef);
- constructor load;
- destructor done;virtual;
- procedure write;virtual;
- procedure deref;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- pvarsym = ^tvarsym;
-
- tvarsym = object(tsym)
- address : longint;
- definition : pdef;
- refs : longint;
- regable : boolean;
-
- { if reg<>R_NO, then the variable is an register variable }
- reg : tregister;
-
- { sets the type of access }
- varspez : tvarspez;
- is_valid : byte;
- constructor init(const n : string;p : pdef);
- constructor load;
- function mangledname : string;virtual;
- function getsize : longint;
- procedure write;virtual;
- procedure deref;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- tpropertysym = object(tsym)
- options : longint;
- proptype : pdef;
- { proppara : pdefcoll; }
- readaccesssym,writeaccesssym : psym;
- readaccessdef,writeaccessdef : pdef;
- index : longint;
- constructor init(const n : string);
- destructor done;virtual;
- constructor load;
- function getsize : longint;virtual;
- procedure write;virtual;
- procedure deref;virtual;
- {$ifdef GDB}
- { I don't know how }
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- {$ifdef TEST_FUNCRET}
- pfuncretsym = ^tfuncretsym;
-
- tfuncretsym = object(tsym)
- funcretprocinfo : pprocinfo;
- funcretdef : pdef;
- address : longint;
- constructor init(const n : string;approcinfo : pprocinfo);
- end;
- {$endif TEST_FUNCRET}
-
- pabsolutesym = ^tabsolutesym;
-
- absolutetyp = (tovar,toasm,toaddr);
-
- tabsolutesym = object(tvarsym)
- abstyp : absolutetyp;
- absseg : boolean;
- ref : psym;
- asmname : pstring;
- { this creates a problem in gen_vmt !!!!!
- because the pdef is not resolved yet !!
- we should fix this }
- constructor load;
- procedure deref;virtual;
- function mangledname : string;virtual;
- procedure write;virtual;
- {constructor init(const s : string;p : pdef;newref : psym);}
- {$ifdef GDB}
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- ptypedconstsym = ^ttypedconstsym;
-
- ttypedconstsym = object(tsym)
- prefix : pstring;
- definition : pdef;
- constructor init(const n : string;p : pdef);
- constructor load;
- destructor done;virtual;
- function mangledname : string;virtual;
- procedure write;virtual;
- procedure deref;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- {$endif GDB}
- end;
-
- tconsttype = (constord,conststring,constreal,constbool,constint,
- constchar,constseta);
-
- pconstsym = ^tconstsym;
-
- tconstsym = object(tsym)
- definition : pdef;
- consttype : tconsttype;
- value : longint;
- constructor init(const n : string;t : tconsttype;v : longint;def : pdef);
- constructor load;
- function mangledname : string;virtual;
- {$ifdef GDB}
- destructor done;virtual;
- {$endif GDB}
- procedure deref;virtual;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- penumsym = ^tenumsym;
-
- tenumsym = object(tsym)
- value : longint;
- definition : penumdef;
- next : penumsym;
- constructor init(const n : string;def : penumdef;v : longint);
- constructor load;
- procedure write;virtual;
- procedure deref;virtual;
- {$ifdef GDB}
- procedure order;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- pprogramsym = ^tprogramsym;
-
- tprogramsym = object(tsym)
- constructor init(const n : string);
- end;
-
- psyssym = ^tsyssym;
-
- tsyssym = object(tsym)
- number : longint;
- constructor init(const n : string;l : longint);
- procedure write;virtual;
- {$ifdef GDB}
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- tcallback = procedure(p : psym);
-
- tsymtablehasharray = array[0..hasharraysize-1] of psym;
-
- psymtablehasharray = ^tsymtablehasharray;
-
- tsymtable = object
- name : pstring;
- datasize : longint;
- wurzel : psym;
- hasharray : psymtablehasharray;
- next : psymtable;
-
- defowner : pdef; { for records and objects }
-
- { only used for parameter symtable to determine the offset relative }
- { to the frame pointer }
- call_offset : longint;
-
- { this saves all definition to allow a proper clean up }
- wurzeldef : pdef;
- symtabletype : tsymtabletype;
- { separate lexlevel from symtable type }
- symtablelevel : byte;
-
- { each symtable gets a number }
- unitid : word;
-
- constructor init(t : tsymtabletype);
- constructor load;
- constructor loadasstruct(typ : tsymtabletype);
- destructor done;virtual;
- procedure check_forwards;
- procedure insert(sym : psym);
- function search(const s : stringid) : psym;
- procedure clear;
- procedure registerdef(p : pdef);
- procedure foreach(proc2call : tcallback);
- procedure allsymbolsused;
- procedure allunitsused;
- {$ifdef CHAINPROCSYMS}
- procedure chainprocsyms;
- {$endif CHAINPROCSYMS}
- procedure write;
- procedure number_units;
- procedure number_defs;
- procedure writeasstruct;
- function getdefnr(l : word) : pdef;
- {$ifdef UseBrowser}
- function getsymnr(l : word) : psym;
- procedure number_symbols;
- procedure write_external_references;
- {$endif UseBrowser}
- {$ifdef GDB}
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- function getnewtypecount : word; virtual;
- end;
-
- tunitsymtable = object(tsymtable)
- checksum,maschstart : longint;
- dbx_count : longint;
- is_stab_written : boolean;
- prev_dbx_counter : plongint;
- dbx_count_ok : boolean;
- unittypecount : word;
- unitsym : punitsym;
-
- constructor init(t : tsymtabletype;const n : string);
- constructor load(const n : string);
- procedure writeasunit;
- {$ifdef GDB}
- procedure orderdefs;
- procedure concattypestabto(asmlist : paasmoutput);
- {$endif GDB}
- function getnewtypecount : word; virtual;
- end;
-
- { definition contains the informations about a type }
- tdeftype = (abstractdef,arraydef,recorddef,pointerdef,orddef,
- stringdef,enumdef,procdef,objectdef,errordef,
- filedef,formaldef,setdef,procvardef,floatdef,
- classrefdef);
-
- tdef = object
- savesize : longint;
- owner : psymtable;
- { this allows to determine by which type the definition was generated }
- sym : ptypesym;
- next : pdef;
- {$ifdef GDB}
- globalnb : word;
- nextglobal : pdef;
- {StabType : word;}
- isstabwritten : boolean;
- {$endif GDB}
- number : word;
- deftype : tdeftype;
-
- function size : longint;virtual;
- {$ifdef GDB}
- function NumberString : string;
- {$endif GDB}
- constructor init;
- {$ifdef GDB}
- constructor load;
- procedure set_globalnb;
- {$endif GDB}
- destructor done;virtual;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- function allstabstring : pchar;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- procedure deref;virtual;
- end;
-
- tfiletype = (ft_text,ft_typed,ft_untyped);
-
- tfiledef = object(tdef)
- public
- filetype : tfiletype;
- typed_as : pdef;
- constructor init(ft : tfiletype;tas : pdef);
- constructor load;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- procedure deref;virtual;
- {private}
- procedure setsize;
- end;
-
- tformaldef = object(tdef)
- constructor init;
- constructor load;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- terrordef = object(tdef)
- constructor init;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- {$endif GDB}
- end;
-
- { tpointerdef and tclassrefdef should get a common
- base class, but I derived tclassrefdef from tpointerdef
- to avoid problems with bugs (FK)
- }
-
- tpointerdef = object(tdef)
- definition : pdef;
- defsym : ptypesym;
- constructor init(def : pdef);
- constructor load;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- procedure deref;virtual;
- end;
-
- tclassrefdef = object(tpointerdef)
- constructor init(def : pdef);
- constructor load;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- tarraydef = object(tdef)
- lowrange : longint;
- highrange : longint;
- rangenr : longint;
- definition : pdef;
- rangedef : pdef;
- function elesize : longint;
- constructor init(l,h : longint;rd : pdef);
- constructor load;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- procedure deref;virtual;
- function size : longint;virtual;
-
- { generates the ranges needed by the asm instruction BOUND (i386)
- or CMP2 (Motorola) }
- procedure genrangecheck;
- end;
-
- trecdef = object(tdef)
- symtable : psymtable;
- constructor init(p : psymtable);
- constructor load;
- destructor done;virtual;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- procedure deref;virtual;
- end;
-
- torddef = object(tdef)
- von : longint;
- bis : longint;
- rangenr : longint;
- typ : tbasetype;
- constructor init(t : tbasetype;v,b : longint);
- constructor load;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- {$endif GDB}
- procedure setsize;
-
- { generates the ranges needed by the asm instruction BOUND }
- { or CMP2 (Motorola) }
- procedure genrangecheck;
- end;
-
- tfloatdef = object(tdef)
- typ : tfloattype;
- constructor init(t : tfloattype);
- constructor load;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- {$endif GDB}
- procedure setsize;
- end;
-
- tabstractprocdef = object(tdef)
- { saves a definition to the return type }
- retdef : pdef;
- { save the procedure options }
- options : longint;
- para1 : pdefcoll;
- constructor init;
- constructor load;
- destructor done;virtual;
- procedure concatdef(p : pdef;vsp : tvarspez);
- procedure deref;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- procedure write;virtual;
- end;
-
- tprocvardef = object(tabstractprocdef)
- constructor init;
- constructor load;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput); virtual;
- {$endif GDB}
- end;
-
- tprocdef = object(tabstractprocdef)
- extnumber : longint;
- nextoverloaded : pprocdef;
- { pointer to the local symbol table }
- localst : psymtable;
- { pointer to the parameter symbol table }
- parast : psymtable;
-
- {$ifdef UseBrowser}
- lastref,defref,lastwritten : pref;
- refcount : longint;
- {$endif UseBrowser}
-
- _class : pobjectdef;
- _mangledname : pchar;
-
- { it's a tree, but this not easy to handle }
- { with the interfaces of units }
- code : pointer;
-
- { true, if the procedure is only declared }
- { (forward procedure) }
- forwarddef : boolean;
-
- { set which contains the modified registers }
- {$ifdef i386}
- usedregisters : byte;
- {$endif}
- {$ifdef m68k}
- usedregisters : word;
- {$endif}
- {$ifdef alpha}
- usedregisters_int : longint;
- usedregisters_fpu : longint;
- {$endif}
- constructor init;
- destructor done;virtual;
- constructor load;
- procedure write;virtual;
- {$ifdef GDB}
- function cplusplusmangledname : string;
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- procedure deref;virtual;
- function mangledname : string;
- procedure setmangledname(const s : string);
- {$ifdef UseBrowser}
- procedure load_references; virtual;
- procedure write_references; virtual;
- procedure write_external_references;
- procedure write_ref_to_file(var f : text);
- {$endif UseBrowser}
- end;
-
- stringtype = (shortstring, longstring, ansistring);
-
- tstringdef = object(tdef)
- string_typ : stringtype;
- len : longint;
- constructor init(l : byte);
- constructor load;
- {$ifdef UseLongString}
- constructor longinit(l : longint);
- constructor longload;
- {$endif UseLongString}
- {$ifdef UseAnsiString}
- constructor ansiinit(l : longint);
- constructor ansiload;
- {$endif UseAnsiString}
- function size : longint;virtual;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- end;
-
- tenumdef = object(tdef)
- max : longint;
- has_jumps : boolean;
- first : penumsym;
- constructor init;
- constructor load;
- destructor done;virtual;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- {$endif GDB}
- end;
-
- tobjectdef = object(tdef)
- childof : pobjectdef;
- name : pstring;
- { privatesyms : psymtable;
- protectedsyms : psymtable; }
- publicsyms : psymtable;
- options : longint;
- constructor init(const n : string;c : pobjectdef);
- destructor done;virtual;
- procedure check_forwards;
- function isrelated(d : pobjectdef) : boolean;
- function size : longint;virtual;
- constructor load;
- procedure write;virtual;
- function vmt_mangledname : string;
- function isclass : boolean;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- {$endif GDB}
- procedure deref;virtual;
- end;
-
- tsettype = (normset,smallset,varset);
-
- tsetdef = object(tdef)
- setof : pdef;
- settype : tsettype;
- constructor init(s : pdef;high : longint);
- constructor load;
- procedure write;virtual;
- {$ifdef GDB}
- function stabstring : pchar;virtual;
- procedure concatstabto(asmlist : paasmoutput);virtual;
- {$endif GDB}
- procedure deref;virtual;
- end;
-
- { inits the symbol table administration }
- procedure init_symtable;
- procedure done_symtable;
- procedure reset_gdb_info;
-
- { searches n in symtable of pd and all anchestors }
- function search_class_member(pd : pobjectdef;const n : string) : psym;
-
- { returns the default property of a class, searches also anchestors }
- function search_default_property(pd : pobjectdef) : ppropertysym;
-
- { get a global symbol }
- function search_a_symtable(const symbol:string;symtabletype:tsymtabletype):Psym;
- procedure getsym(const s : stringid;notfounderror : boolean);
- procedure getsymonlyin(p : psymtable;const s : stringid);
-
- { writes an unit with the given name }
- procedure writeunitas(const s : string;unit_symtable : punitsymtable);
-
- { deletes a symbol table from the symbol table stack }
- procedure dellexlevel;
- {$ifdef DEBUG}
- procedure test_symtablestack;
- {$endif DEBUG}
- { saves a forward pointer defintion .... }
- procedure save_forward(ppd : ppointerdef;typesym : ptypesym);
-
- { .... resolves this forward definitions }
- procedure resolve_forwards;
-
- var
- { for STAB debugging }
- globaltypecount : word;
- pglobaltypecount : pword;
-
- registerdef : boolean; { true, wenn Definitionen }
- { registriert werden sollen }
-
- symtablestack : psymtable; { Wurzel der verketteten Liste von }
- { Symboltabellen }
-
- srsym : psym; { enthlt das Ergebnis der letzten }
- srsymtable : psymtable; { Suche nach einem Symbol }
-
- forwardsallowed : boolean; { true, wenn Pointertypen "forward" }
- { eingefgt werden drfen }
-
- constsymtable : psymtable; { Symboltabelle in die die }
- { Konstanten von z.B. Aufzhlungs- }
- { typen eingefgt werden }
-
- voiddef : porddef; { Zeiger auf eine void-Definition }
- { wird von quelltext initialisiert }
- { (ist resulttype einer Procedure) }
- voidpointerdef : ppointerdef;
- { Zeiger auf "void"-Pointerdef }
-
- u32bitdef : porddef; { Zeiger fr resulttype von }
- s32bitdef : porddef; { Zeiger fr resulttype von }
- { intconstn }
-
- u8bitdef : porddef; { Pointer auf 8-Bit unsigned }
- u16bitdef : porddef; { Pointer auf 16-Bit unsigned }
-
- c64floatdef : pfloatdef; { Zeiger fr resulttype von }
- { realconstn }
- s80floatdef : pfloatdef; { pointer to type of temp. floats }
-
- s32fixeddef : pfloatdef; { pointer to type of temp. fixed }
-
- cstringdef : pstringdef; { pointer to type of short string const }
-
- {$ifdef UseLongString}
- clongstringdef : pstringdef; { pointer to type of long string const }
- {$endif UseLongString}
-
- {$ifdef UseAnsiString}
- cansistringdef : pstringdef; { pointer to type of ansi string const }
- {$endif UseAnsiString}
-
- cchardef : porddef; { Zeiger fr resulttype von }
- { charconstn }
-
- cfiledef : pfiledef; { get the same definition for all file }
- { uses for stabs }
- firstglobaldef, lastglobaldef : pdef;
-
- class_tobject : pobjectdef; { pointer to the anchestor of all }
- { clases }
-
- booldef : porddef; { pointer to boolean type }
-
- aktprocsym : pprocsym; { Zeiger auf den Symboltablellen- }
- { eintrag der momentan geparseten }
- { procedure }
-
- procprefix : string; { eindeutige Namen bei geschachtel- }
- { ten Unterprogrammen erzeugen }
-
- lexlevel : longint; { level of code }
- { 1 for main procedure }
- { 2 for normal function or proc }
- { higher for locals }
-
- macros : psymtable; { Zeiger auf die Symboltabelle mit }
- { Makros }
-
- read_member : boolean; { true, wenn Members aus einer PPU- }
- { Datei gelesen werden, d.h. ein }
- { varsym seine Adresse einlesen soll }
-
- generrorsym : psym; { Jokersymbol, wenn das richtige }
- { Symbol nicht gefunden wird }
-
- generrordef : pdef; { Jokersymbol fr eine fehlerhafte }
- { Typdefinition }
-
- aktobjectdef : pobjectdef; { used for private functions check !! }
-
- overloaded_operators : array[PLUS..last_overloaded] of pprocsym;
- { unequal is not equal}
- const
- overloaded_names : array [PLUS..last_overloaded] of string[16] =
- ('plus','minus','star','slash','equal',
- 'greater','lower','greater_or_equal',
- 'lower_or_equal','as','is','in','sym_diff',
- 'caret','assign');
-
- {$ifdef GDB}
- function typeglobalnumber(const s : string) : string;
- {$endif GDB}
-
- function globaldef(const s : string) : pdef;
-
- procedure maybe_concat_external(symt : psymtable;const name : string);
-
- { pointer to the system unit, if the system unit is loaded }
- const systemunit : punitsymtable = nil;
- current_object_option : symprop = sp_public;
- {$ifdef UseBrowser}
- use_browser : boolean = true;
- {$endif UseBrowser}
-
-
- implementation
-
- {$ifdef TP}
- {$F+}
- {$endif TP}
-
- var
- aktrecordsymtable : psymtable; { zeigt auf die Symboltabelle des }
- { Records, das momentan aus einer }
- { PPU-Datei gelesen wird }
-
-
- {to dispose the global symtable of a unit }
- const
- dispose_global: boolean =false;
- object_options : boolean = false;
- memsizeinc = 2048; { for long stabstrings }
- tagtypes : Set of tdeftype =
- [recorddef,enumdef,
- {$IfNDef GDBKnowsStrings}
- stringdef,
- {$EndIf not GDBKnowsStrings}
- {$IfNDef GDBKnowsFiles}
- filedef,
- {$EndIf not GDBKnowsFiles}
- objectdef];
-
- var
- { this is for a faster execution }
- ppufile : tbufferedfile;
-
- procedure writestring(s : string);
-
- begin
- ppufile.write_data(s,length(s)+1);
- end;
-
- procedure writeset(var s); {You cannot pass an array[0..31]
- of byte!}
- begin
- ppufile.write_data(s,32);
- end;
-
- procedure writedefref(p : pdef);
-
- begin
- if p=nil then
- ppufile.write_long($ffffffff)
- else
- begin
- if (p^.owner^.symtabletype=recordsymtable) or
- (p^.owner^.symtabletype=objectsymtable) then
- ppufile.write_word($ffff)
- else ppufile.write_word(p^.owner^.unitid);
- ppufile.write_word(p^.number);
- end;
- end;
-
- {$ifdef UseBrowser}
- procedure writesymref(p : psym);
-
- begin
- if p=nil then
- writelong($ffffffff)
- else
- begin
- if (p^.owner^.symtabletype=recordsymtable) or
- (p^.owner^.symtabletype=objectsymtable) then
- writeword($ffff)
- else writeword(p^.owner^.unitid);
- writeword(p^.indexnb);
- end;
- end;
- {$endif UseBrowser}
-
- procedure writeunitas(const s : string;unit_symtable : punitsymtable);
-
- {$ifdef UseBrowser}
- var
- pus : punitsymtable;
- {$endif UseBrowser}
-
- begin
- Message1(unit_u_ppu_write,s);
-
- { open en init ppufile }
- ppufile.init(s,ppubufsize);
- ppufile.change_endian:=source_info.endian<>target_info.endian;
- ppufile.rewrite;
- if ioresult<>0 then
- Message(unit_f_ppu_cannot_write);
-
- { create and write header }
- unitheader[8]:=char(byte(target_info.target));
- if use_dbx then
- current_module^.flags:= current_module^.flags or uf_uses_dbx;
- {$ifdef UseBrowser}
- if use_browser then
- current_module^.flags:= current_module^.flags or uf_uses_browser;
- {$endif UseBrowser}
- if target_info.endian=en_big_endian then
- current_module^.flags:=current_module^.flags or uf_big_endian;
- unitheader[9]:=char(current_module^.flags);
- ppufile.write_data(unitheader,sizeof(unitheader));
-
- ppufile.clear_crc;
- ppufile.do_crc:=true;
- unit_symtable^.writeasunit;
- ppufile.flush;
- ppufile.do_crc:=false;
-
- {$ifdef UseBrowser}
- { write all new references to old unit elements }
- pus:=punitsymtable(unit_symtable^.next);
- if use_browser then
- while assigned(pus) do
- begin
- if pus^.symtabletype = unitsymtable then
- pus^.write_external_references;
- pus:=punitsymtable(pus^.next);
- end;
- {$endif UseBrowser}
-
- { writes the checksum }
- ppufile.seek(10);
- current_module^.crc:=ppufile.getcrc;
- ppufile.write_data(current_module^.crc,4);
- ppufile.flush;
-
- ppufile.done;
- end;
-
-
- function readbyte : byte;
-
- var
- count : longint;
- b : byte;
-
- begin
- current_module^.ppufile^.read_data(b,sizeof(byte),count);
- readbyte:=b;
- if count<>1 then
- Message(unit_f_ppu_read_error);
- end;
-
- function readword : word;
-
- var
- count : longint;
- w : word;
-
- begin
- current_module^.ppufile^.read_data(w,sizeof(word),count);
- {$IFDEF BIG_ENDIAN}
- w:=swap(w);
- {$ENDIF}
- readword:=w;
- if count<>sizeof(word) then
- Message(unit_f_ppu_read_error);
- end;
-
- function readlong : longint;
-
- var
- count,l : longint;
- w1, w2 : word;
-
- begin
- current_module^.ppufile^.read_data(l,sizeof(longint),count);
- {$ifdef BIG_ENDIAN}
- w1:=l and $ffff;
- w2:=l shr 16;
- l:=swap(w2)+(longint(swap(w1)) shl 16);
- {$endif}
- readlong:=l;
- if count<>sizeof(longint) then
- Message(unit_f_ppu_read_error);
- end;
-
- function readdouble : double;
-
- var
- count : longint;
- d : double;
-
- begin
- current_module^.ppufile^.read_data(d,sizeof(double),count);
- readdouble:=d;
- if count<>sizeof(double) then
- Message(unit_f_ppu_read_error);
- end;
-
- function readstring : string;
-
- var
- s : string;
- count : longint;
-
- begin
- s[0]:=char(readbyte);
- current_module^.ppufile^.read_data(s[1],ord(s[0]),count);
- if count<>ord(s[0]) then
- Message(unit_f_ppu_read_error);
- readstring:=s;
- end;
-
- {***SETCONST}
- procedure readset(var s); {You cannot pass an array [0..31] of byte.}
-
- var count:longint;
-
- begin
- current_module^.ppufile^.read_data(s,32,count);
- if count<>32 then
- Message(unit_f_ppu_read_error);
- end;
- {***}
-
- function readdefref : pdef;
-
- var
- hd : pdef;
-
- begin
- longint(hd):=readword;
- longint(hd):=longint(hd) or (longint(readword) shl 16);
- readdefref:=hd;
- end;
-
- procedure resolvedef(var d : pdef);
-
- begin
- if longint(d)=$ffffffff then
- d:=nil
- else
- begin
- if (longint(d) and $ffff)=$ffff then
- d:=aktrecordsymtable^.getdefnr(longint(d) shr 16)
- else
- d:=psymtable(current_module^.map^[longint(d) and $ffff])^.getdefnr(longint(d) shr 16);
- end;
- end;
-
- {$ifdef UseBrowser}
- function readsymref : psym;
-
- var
- hd : psym;
-
- begin
- longint(hd):=readword;
- longint(hd):=longint(hd) or (longint(readword) shl 16);
- readsymref:=hd;
- end;
-
- procedure resolvesym(var d : psym);
-
- begin
- if longint(d)=$ffffffff then
- d:=nil
- else
- begin
- if (longint(d) and $ffff)=$ffff then
- d:=aktrecordsymtable^.getsymnr(longint(d) shr 16)
- else
- d:=psymtable(current_module^.map^[longint(d) and $ffff])^.getsymnr(longint(d) shr 16);
- end;
- end;
- {$endif UseBrowser}
-
- {$I+}
- procedure getsym(const s : stringid;notfounderror : boolean);
-
- begin
- srsymtable:=symtablestack;
- while assigned(srsymtable) do
- begin
- srsym:=srsymtable^.search(s);
- if assigned(srsym) then exit
- else srsymtable:=srsymtable^.next;
- end;
- if forwardsallowed then
- begin
- srsymtable:=symtablestack;
- srsym:=new(ptypesym,init(s,nil));
- srsym^.properties:=sp_forwarddef;
- srsymtable^.insert(srsym);
- end
- else if notfounderror then
- begin
- Message1(sym_e_id_not_found,s);
- srsym:=generrorsym;
- end
- else srsym:=nil;
- end;
-
- function search_a_symtable(const symbol:string;symtabletype:tsymtabletype):Psym;
-
- {Search for a symbol in a specified symbol table. Returns nil if
- the symtable is not found, and also if the symbol cannot be found
- in the desired symtable.}
-
- var hsymtab:Psymtable;
- res:Psym;
-
- begin
- res:=nil;
- hsymtab:=symtablestack;
- while (hsymtab<>nil) and (hsymtab^.symtabletype<>symtabletype) do
- hsymtab:=hsymtab^.next;
- if hsymtab<>nil then
- {We found the desired symtable. Now check if the symbol we
- search for is defined in it.}
- res:=hsymtab^.search(symbol);
- search_a_symtable:=res;
- end;
-
- procedure getsymonlyin(p : psymtable;const s : stringid);
-
- begin
- { the caller have to take care if srsym=nil (FK) }
- srsym:=nil;
- if assigned(p) then
- begin
- srsymtable:=p;
- srsym:=srsymtable^.search(s);
- if assigned(srsym) then
- exit
- else
- Message1(sym_e_id_not_found,s);
- end;
- end;
-
- procedure dellexlevel;
-
- var
- p : psymtable;
-
- begin
- p:=symtablestack;
- symtablestack:=p^.next;
-
- { symbol tables of unit interfaces are never disposed }
- { this is handle by the unit unitm }
- if ((p^.symtabletype<>unitsymtable) and
- (p^.symtabletype<>globalsymtable)) or
- dispose_global then
- dispose(p,done);
- end;
-
- {$ifdef DEBUG}
- procedure test_symtablestack;
- var
- p : psymtable;
- i : longint;
- begin
- p:=symtablestack;
- i:=0;
- while assigned(p) do
- begin
- inc(i);
- p:=p^.next;
- if i>500 then
- Message(sym_f_internal_error_in_symtablestack);
- end;
- end;
- {$endif DEBUG}
-
- constructor tprocsym.init(const n : string);
-
- begin
- tsym.init(n);
- typ:=procsym;
- definition:=nil;
- owner:=nil;
- {$ifdef GDB}
- is_global := false;
- {$endif GDB}
- end;
-
- constructor tprocsym.load;
-
- begin
- tsym.load;
- typ:=procsym;
- definition:=pprocdef(readdefref);
- {$ifdef GDB}
- is_global := false;
- {$endif GDB}
- end;
-
- destructor tprocsym.done;
-
- begin
- check_forward;
- tsym.done;
- end;
-
- function tprocsym.mangledname : string;
-
- begin
- mangledname:=definition^.mangledname;
- end;
-
- function demangledparas(s : string) : string;
-
- var
- r : string;
- l : longint;
-
- begin
- demangledparas:='';
- r:=',';
- { delete leading $$'s }
- l:=pos('$$',s);
- while l<>0 do
- begin
- delete(s,1,l+1);
- l:=pos('$$',s);
- end;
- l:=pos('$',s);
- if l=0 then
- exit;
- delete(s,1,l);
- l:=pos('$',s);
- if l=0 then
- l:=length(s)+1;
- while s<>'' do
- begin
- r:=r+copy(s,1,l-1)+',';
- delete(s,1,l);
- end;
- delete(r,1,1);
- delete(r,length(r),1);
- demangledparas:=r;
- end;
-
- procedure tprocsym.check_forward;
-
- var
- pd : pprocdef;
-
- begin
- pd:=definition;
- while assigned(pd) do
- begin
- if pd^.forwarddef then
- begin
- {$ifdef GDB}
- if assigned(pd^._class) then
- Message1(sym_e_forward_not_resolved,pd^._class^.name^+'.'+name+'('+demangledparas(pd^.mangledname)+')')
- else
- {$endif GDB}
- Message1(sym_e_forward_not_resolved,name+'('+demangledparas(pd^.mangledname)+')')
- end;
- pd:=pd^.nextoverloaded;
- end;
- end;
-
- procedure tprocsym.deref;
- var t : ttoken;
-
- begin
- resolvedef(pdef(definition));
- for t:=PLUS to last_overloaded do
- if (overloaded_operators[t]=nil) and
- (name=overloaded_names[t]) then
- overloaded_operators[t]:=@self;
- end;
-
- constructor tprogramsym.init(const n : string);
-
- begin
- tsym.init(n);
- typ:=programsym;
- end;
-
- constructor tsymtable.init(t : tsymtabletype);
-
- begin
- symtabletype:=t;
- symtablelevel:=0;
- wurzel:=nil;
- defowner:=nil;
- unitid:=0;
- next:=nil;
- name:=nil;
- call_offset:=0;
- if symtabletype=objectsymtable then
- datasize:=4
- else
- datasize:=0;
- wurzeldef:=nil;
- hasharray:=nil;
- end;
-
- constructor tunitsymtable.init(t : tsymtabletype; const n : string);
-
- var
- w : word;
-
- begin
- tsymtable.init(t);
- name:=stringdup(n);
- unitsym:=nil;
- {$ifdef GDB}
- if t = globalsymtable then
- begin
- prev_dbx_counter := dbx_counter;
- dbx_counter := @dbx_count;
- end;
- dbx_count := 0;
- unitid:=0;
- {$endif GDB}
- new(hasharray);
- for w:=0 to hasharraysize-1 do
- hasharray^[w]:=nil;
- is_stab_written:=false;
- {$ifdef GDB}
- if use_dbx then
- begin
- if (symtabletype=globalsymtable) then
- pglobaltypecount := @unittypecount;
- debuglist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
- +tostr(N_BINCL)+',0,0,0'))));
- unitid:=current_module^.unitcount;
- inc(current_module^.unitcount);
- debuglist^.concat(new(pai_direct,init(strpnew('# Global '+name^+' has index '+
- +tostr(unitid)))));
- end;
- {$endif GDB}
- end;
-
- procedure derefsym(p : psym);
-
- begin
- p^.deref;
- end;
-
- procedure derefsymsdelayed(p : psym);
-
- begin
- if p^.typ in [absolutesym,propertysym] then
- p^.deref;
- end;
-
- constructor tsymtable.load;
-
- var
- hp : pdef;
- b : byte;
- counter : word;
- sym : psym;
- ofile : string;
- ii:longint;
-
- begin
- current_module^.map^[0]:=@self;
-
- symtabletype:=unitsymtable;
- symtablelevel:=0;
-
- { unused for units }
- call_offset:=0;
-
- { reset hash array }
- new(hasharray);
- for counter:=0 to hasharraysize-1 do
- hasharray^[counter]:=nil;
-
- datasize:=0;
- wurzel:=nil;
- next:=nil;
- wurzeldef:=nil;
- defowner:=nil;
-
- unitid:=0;
- defowner:=nil;
-
- { read the definitions }
- counter:=0;
- repeat
- b:=readbyte;
- case b of
- ibpointerdef : hp:=new(ppointerdef,load);
- ibarraydef : hp:=new(parraydef,load);
- iborddef : hp:=new(porddef,load);
- ibfloatdef : hp:=new(pfloatdef,load);
- ibprocdef : hp:=new(pprocdef,load);
- ibstringdef : hp:=new(pstringdef,load);
- {$ifdef UseLongString}
- iblongstringdef : hp:=new(pstringdef,longload);
- {$endif UseLongString}
- {$ifdef UseAnsiString}
- ibansistringdef : hp:=new(pstringdef,ansiload);
- {$endif UseAnsiString}
- ibrecorddef : hp:=new(precdef,load);
- ibobjectdef : begin
- hp:=new(pobjectdef,load);
- { defines the VMT external }
- { owner isn't set in the constructor load }
- { externals^.concat(new(pai_external,init('VMT_'+name^+'$_'+pobjectdef(hp)^.name^))); }
- end;
- ibfiledef : hp:=new(pfiledef,load);
- ibformaldef : hp:=new(pformaldef,load);
- ibenumdef : hp:=new(penumdef,load);
- ibclassrefdef : hp:=new(pclassrefdef,load);
- { ibinitunit : usedunits^.insert(readstring); }
- iblibraries : begin
- ofile:=readstring;
- Linker.AddLibraryFile(ofile);
- current_module^.LinkLibFiles.Insert(ofile);
- end;
- iblinkofile : begin
- ofile:=readstring;
- if (current_module^.ppufile^.path<>nil) and
- not path_absolute(ofile) then
- Linker.AddObjectFile(current_module^.ppufile^.path^+ofile)
- else
- Linker.AddObjectFile(ofile);
- end;
- ibsetdef : hp:=new(psetdef,load);
- ibprocvardef : hp:=new(pprocvardef,load);
- ibend : break;
- else Message1(unit_f_ppu_invalid_entry,tostr(b));
- end;
-
- if not (b in [ibloadunit,ibinitunit,iblinkofile,iblibraries]) then
- begin
- { each definition get a number }
- hp^.number:=counter;
- inc(counter);
-
- hp^.next:=wurzeldef;
- wurzeldef:=hp;
- end;
- until false;
-
- { solve the references of the symbols }
- hp:=wurzeldef;
-
- { for each definition }
- while assigned(hp) do
- begin
- hp^.deref;
-
- { insert also the owner }
- hp^.owner:=@self;
-
- hp:=hp^.next;
- end;
-
- { read the symbols }
- repeat
- b:=readbyte;
- case b of
- ibtypesym : sym:=new(ptypesym,load);
- ibprocsym : sym:=new(pprocsym,load);
- ibconstsym : sym:=new(pconstsym,load);
- ibvarsym : sym:=new(pvarsym,load);
- ibabsolutesym : sym:=new(pabsolutesym,load);
- ibaufzaehlsym : sym:=new(penumsym,load);
- ibtypedconstsym : sym:=new(ptypedconstsym,load);
- ibpropertysym : sym:=new(ppropertysym,load);
- ibend : break;
- else Message1(unit_f_ppu_invalid_entry,tostr(b));
- end;
- { don't deref absolute symbols there, because it's possible }
- { that the var sym which the absolute sym refers, isn't }
- { loaded }
- { but syms must be derefered to determine the definition }
- { because must know the varsym size when inserting the symbol }
- if not(b in [ibabsolutesym,ibpropertysym]) then
- sym^.deref;
- insert(sym);
- until false;
- {$ifdef tp}
- foreach(derefsymsdelayed);
- {$else}
- foreach(@derefsymsdelayed);
- {$endif}
- { symbol numbering for references }
- {$ifdef UseBrowser}
- number_symbols;
- {$endif UseBrowser}
-
- end;
-
- constructor tunitsymtable.load(const n : string);
-
- var storeGlobalTypeCount : pword;
- b : byte;
- begin
- name:=stringdup(n);
- unitsym:=nil;
- unitid:=0;
- dbx_count := 0;
- if (current_module^.flags and uf_uses_dbx)<>0 then
- begin
- storeGlobalTypeCount:=PGlobalTypeCount;
- PglobalTypeCount:=@UnitTypeCount;
- end;
- inherited load;
- if (current_module^.flags and uf_uses_dbx)<>0 then
- begin
- b := readbyte;
- if b <> ibdbxcount then
- Message(unit_f_ppu_dbx_count_problem)
- else
- dbx_count := readlong;
- dbx_count_ok := true;
- b := readbyte;
- if b <> ibend then
- Message1(unit_f_ppu_invalid_entry,tostr(b));
- PGlobalTypeCount:=storeGlobalTypeCount;
- end;
- is_stab_written:=false;
- end;
-
- constructor tsymtable.loadasstruct(typ : tsymtabletype);
-
- var
- hp : pdef;
- b : byte;
- counter : word;
- sym : psym;
-
- begin
- symtabletype:=typ;
- hasharray:=nil;
- aktrecordsymtable:=@self;
- name:=nil;
- if symtabletype=objectsymtable then
- datasize:=4
- else
- datasize:=0;
- { isn't used there }
- call_offset := 0;
- wurzel:=nil;
- next:=nil;
- wurzeldef:=nil;
- { also unused }
- unitid:=0;
-
- { read definitions }
- counter:=0;
- repeat
- b:=readbyte;
- case b of
- ibpointerdef : hp:=new(ppointerdef,load);
- ibarraydef : hp:=new(parraydef,load);
- iborddef : hp:=new(porddef,load);
- ibfloatdef : hp:=new(pfloatdef,load);
- ibprocdef : hp:=new(pprocdef,load);
- ibstringdef : hp:=new(pstringdef,load);
- ibrecorddef : hp:=new(precdef,load);
- ibobjectdef : hp:=new(pobjectdef,load);
- ibenumdef : hp:=new(penumdef,load);
- ibsetdef : hp:=new(psetdef,load);
- ibprocvardef : hp:=new(pprocvardef,load);
- ibfiledef : hp:=new(pfiledef,load);
- ibclassrefdef : hp:=new(pclassrefdef,load);
- ibformaldef : hp:=new(pformaldef,load);
- ibend : break;
- else Message1(unit_f_ppu_invalid_entry,tostr(b));
- end;
-
- { each def gets a number }
- hp^.number:=counter;
- inc(counter);
- hp^.next:=wurzeldef;
- wurzeldef:=hp;
- until false;
- { the references are solve in trecdef^.deref }
- { now read the symbols }
- repeat
- b:=readbyte;
- case b of
- ibtypesym : sym:=new(ptypesym,load);
- ibprocsym : sym:=new(pprocsym,load);
- ibconstsym : sym:=new(pconstsym,load);
- ibvarsym : sym:=new(pvarsym,load);
- ibabsolutesym : sym:=new(pabsolutesym,load);
- ibaufzaehlsym : sym:=new(penumsym,load);
- ibtypedconstsym : sym:=new(ptypedconstsym,load);
- ibpropertysym : sym:=new(ppropertysym,load);
- ibend : break;
- else Message1(unit_f_ppu_invalid_entry,tostr(b));
- end;
- insert(sym);
- until false;
- end;
-
- destructor tsymtable.done;
-
- var
- hp : pdef;
- {$ifdef GDB}
- last : pdef;
- {$endif GDB}
- begin
- { erst die Eintrge loeschen, da procsym's noch ihre Definitionen }
- { auf unaufgelste "forwards" ueberpruefen }
- clear;
- {$ifdef GDB}
- stringdispose(name);
- {$endif GDB}
- hp:=wurzeldef;
- {$ifdef GDB}
- last := Nil;
- {$endif GDB}
- while assigned(hp) do
- begin
- {$ifdef GDB}
- if hp^.owner=@self then
- begin
- if assigned(last) then last^.next := hp^.next;
- {$endif GDB}
- wurzeldef:=hp^.next;
- dispose(hp,done);
- {$ifdef GDB}
- end else
- begin
- last := hp;
- wurzeldef:=hp^.next;
- end;
- {$endif GDB}
- hp:=wurzeldef;
- end;
-
- end;
-
- function tsymtable.getnewtypecount : word;
- begin
- getnewtypecount:=pglobaltypecount^;
- inc(pglobaltypecount^);
- end;
-
- function tunitsymtable.getnewtypecount : word;
-
- begin
- if symtabletype = staticsymtable then
- getnewtypecount:=tsymtable.getnewtypecount
- else
- begin
- getnewtypecount:=unittypecount;
- inc(unittypecount);
- end;
- end;
-
- procedure check_procsym_forward(sym : psym);
-
- begin
- if sym^.typ=procsym then
- pprocsym(sym)^.check_forward
- { check also object method table }
- { we needn't to test the def list }
- { because each object has to have a type sym }
- else if (sym^.typ=typesym) and
- (ptypesym(sym)^.definition^.deftype=objectdef) then
- pobjectdef(ptypesym(sym)^.definition)^.check_forwards;
- end;
-
- { checks, if all procsyms }
- { and methods are defined }
- procedure tsymtable.check_forwards;
-
- begin
- {$ifdef tp}
- foreach(check_procsym_forward);
- {$else}
- foreach(@check_procsym_forward);
- {$endif}
- end;
-
- {$ifdef UseBrowser }
- procedure add_external_ref(sym : psym);
-
- begin
- sym^.write_external_references;
- end;
-
- { writes all references to elements in other units }
- procedure tsymtable.write_external_references;
-
- begin
- {$ifdef tp}
- foreach(add_external_ref);
- {$else}
- foreach(@add_external_ref);
- {$endif}
- end;
- {$endif UseBrowser }
-
- function tsymtable.getdefnr(l : word) : pdef;
-
- var
- hp : pdef;
-
- begin
- hp:=wurzeldef;
- while (assigned(hp)) and (hp^.number<>l) do
- hp:=hp^.next;
- getdefnr:=hp;
- end;
-
- procedure tsymtable.registerdef(p : pdef);
-
- begin
- p^.next:=wurzeldef;
- wurzeldef:=p;
- p^.owner:=@self;
- end;
-
- procedure tsymtable.clear;
-
- var
- w : integer;
-
- begin
- { remove no entry from a withsymtable as it is only a pointer to the
- recorddef or objectdef symtable }
- if symtabletype=withsymtable then exit;
- { remove all entry from a symbol table }
- if assigned(wurzel) then
- dispose(wurzel,done);
- if assigned(hasharray) then
- begin
- for w:=0 to hasharraysize-1 do
- if assigned(hasharray^[w]) then
- dispose(hasharray^[w],done);
- dispose(hasharray);
- end;
- end;
-
- {$ifdef UseBrowser}
- function tsymtable.getsymnr(l : word) : psym;
-
- var
- hp : psym;
- i :word;
-
- begin
- getsymnr:=nil;
- if assigned(hasharray) then
- begin
- hp:=nil;
- for i:=0 to hasharraysize do
- if hasharray^[i]^.indexnb>=l then
- begin
- hp:=hasharray^[i];
- break;
- end;
- end
- else
- hp:=wurzel;
- while assigned(hp) do
- begin
- if hp^.indexnb<l then
- hp:=hp^.right
- else
- if hp^.indexnb>l then
- hp:=hp^.left
- else
- begin
- getsymnr:=hp;
- exit;
- end;
- end;
- end;
-
- procedure tsymtable.number_symbols;
- var index,i : longint;
-
- procedure numbersym(var osym : psym);
-
- begin
- if osym=nil then exit;
- numbersym(osym^.left);
- osym^.indexnb:=index;
- inc(index);
- numbersym(osym^.right);
- end;
-
- begin
- index:=1;
- if assigned(hasharray) then
- for i:=0 to hasharraysize-1 do
- numbersym(hasharray^[i])
- else
- numbersym(wurzel);
- end;
- {$endif UseBrowser}
-
- {$ifdef CHAINPROCSYMS}
- procedure chainprocsym(p : psym);forward;
- {$endif CHAINPROCSYMS}
-
- function getspeedvalue(const s : string) : longint;
-
- var
- l : longint;
- w : word;
-
- begin
- l:=0;
- for w:=1 to length(s) do
- l:=l+ord(s[w]);
- getspeedvalue:=l;
- end;
-
- procedure tsymtable.insert(sym : psym);
- {$ifdef UseBrowser}
- var ref : pref;
- {$endif UseBrowser}
-
- procedure _insert(var osym : psym);
-
- {To prevent TP from allocating temp space for temp strings, we allocate
- some temp strings manually. We can use two temp strings, plus a third
- one that TP adds, where TP alone needs five temp strings!. Storing
- these on the heap saves even more, totally 1016 bytes per recursion!}
-
- var s1,s2:^string;
-
- begin
- if osym=nil then
- osym:=sym
- { speedvalue is used, to allow a fast insert }
- else if osym^.speedvalue>sym^.speedvalue then _insert(osym^.right)
- else if osym^.speedvalue<sym^.speedvalue then _insert(osym^.left)
- else
- begin
- new(s1);
- new(s2);
- s1^:=osym^.name;
- s2^:=sym^.name;
- if s1^>s2^ then
- begin
- dispose(s1);
- dispose(s2);
- _insert(osym^.right)
- end
- else if s1^<s2^ then
- begin
- dispose(s1);
- dispose(s2);
- _insert(osym^.left)
- end
- else
- begin
- dispose(s2);
- if (osym^.typ=typesym) and (osym^.properties=sp_forwarddef) then
- begin
- dispose(s1);
- if (sym^.typ<>typesym) then
- Message(sym_f_id_already_typed);
- {
- if (ptypesym(sym)^.definition^.deftype<>recorddef) and
- (ptypesym(sym)^.definition^.deftype<>objectdef) then
- Message(sym_f_type_must_be_rec_or_class);
- }
- ptypesym(osym)^.definition:=ptypesym(sym)^.definition;
- osym^.properties:=sp_public;
- { resolve the definition right now !! }
- {$ifdef UseBrowser}
- {forward types have two defref chained
- the first corresponding to the location
- of the
- ptype = ^ttype;
- and the second
- to the line
- ttype = record }
- new(ref,init(nil));
- ref^.nextref:=osym^.defref;
- osym^.defref:=ref;
- {$endif UseBrowser}
- ptypesym(osym)^.forwardpointer^.definition:=ptypesym(osym)^.definition;
- {$ifndef GDB}
- dispose(sym);
- {$else GDB}
- if ptypesym(osym)^.definition^.sym = ptypesym(sym) then
- ptypesym(osym)^.definition^.sym := ptypesym(osym);
- ptypesym(osym)^.isusedinstab := true;
- if (cs_debuginfo in aktswitches) and assigned(debuglist) then
- osym^.concatstabto(debuglist);
- { don't do a done on sym
- because it also disposes left and right !!}
- dispose(sym);
- {$endif GDB}
- end
- else
- begin
- dispose(s1);
- Message1(sym_e_duplicate_id,sym^.name);
- end;
- end;
- end;
- end;
-
- var
- l : longint;
- hp : psymtable;
- hsym : psym;
-
- begin
- { bei Symbolen fr Variablen die Adresse eintragen, }
- { und Gráe der Symboltabellendaten berechnen }
- {$ifdef GDB}
- sym^.owner:=@self;
- {$endif GDB}
- {$ifdef CHAINPROCSYMS}
- { set the nextprocsym field }
- if sym^.typ=procsym then
- chainprocsym(sym);
- {$endif CHAINPROCSYMS}
- { handle static variables of objects especially }
- if read_member and (symtabletype=objectsymtable) and
- (sym^.typ=varsym) and
- ((pvarsym(sym)^.properties and sp_static)<>0) then
- begin
- { the data filed is generated in parser.pas
- with a tobject_FIELDNAME variable }
- { this symbol can't be loaded to a register }
- pvarsym(sym)^.regable:=false;
- end
- else if (sym^.typ=varsym) and not(read_member) then
- begin
- { made problems with parameters etc. ! (FK) }
-
- { check for instance of an abstract object or class }
- {
- if (pvarsym(sym)^.definition^.deftype=objectdef) and
- ((pobjectdef(pvarsym(sym)^.definition)^.options and oois_abstract)<>0) then
- Message(sym_e_no_instance_of_abstract_object);
- }
-
-
- { bei einer lokalen Symboltabelle erst! erhhen, da der }
- { Wert in codegen.secondload dann mit minus verwendet }
- { wird }
- l:=pvarsym(sym)^.getsize;
- if symtabletype=localsymtable then
- begin
- pvarsym(sym)^.is_valid := 0;
- inc(datasize,l);
- {$ifdef m68k}
- { word alignment required for motorola }
- if (l=1) then
- inc(datasize,1)
- else
- {$endif}
- if (l>=4) and ((datasize and 3)<>0) then
- inc(datasize,4-(datasize and 3))
- else if (l>=2) and ((datasize and 1)<>0) then
- inc(datasize,2-(datasize and 1));
-
- pvarsym(sym)^.address:=datasize;
- end
- else if symtabletype=staticsymtable then
- begin
- {$ifdef MAKELIB}
- bsssegment^.concat(new(pai_cut,init));
- {$endif MAKELIB}
- {$ifdef GDB}
- if cs_debuginfo in aktswitches then
- begin
- sym^.concatstabto(bsssegment);
- end;
- {$endif GDB}
- {$ifndef MAKELIB}
- bsssegment^.concat(new(pai_datablock,init(sym^.mangledname,l)));
- {$else MAKELIB}
- { we need to change this to a global symbol }
- bsssegment^.concat(new(pai_datablock,init_global(sym^.mangledname,l)));
- {$endif MAKELIB}
- inc(datasize,l);
-
- { this symbol can't be loaded to a register }
- pvarsym(sym)^.regable:=false;
- end
- else if symtabletype=globalsymtable then
- begin
- {$ifdef MAKELIB}
- bsssegment^.concat(new(pai_cut,init));
- {$endif MAKELIB}
- {$ifdef GDB}
- if cs_debuginfo in aktswitches then
- begin
- sym^.concatstabto(bsssegment);
- { this has to be added so that the debugger knows where to find
- the global variable
- Doesn't work !!
-
- bsssegment^.concat(new(pai_symbol,init('_'+sym^.name))); }
- end;
- {$endif GDB}
- bsssegment^.concat(new(pai_datablock,init_global(
- sym^.mangledname,l)));
- inc(datasize,l);
- {$ifdef MAKELIB}
- bsssegment^.concat(new(pai_cut,init));
- {$endif MAKELIB}
-
- { this symbol can't be loaded to a register }
- pvarsym(sym)^.regable:=false;
- end
- else if symtabletype in [recordsymtable,objectsymtable] then
- begin
- { align record and object fields }
- if aktpackrecords=2 then
- begin
- { align to word }
- if (l>=2) and ((datasize and 1)<>0) then
- inc(datasize);
- end
- else if aktpackrecords=4 then
- begin
- { align to dword }
- if (l>=3) and ((datasize and 3)<>0) then
- inc(datasize,4-(datasize and 3))
- { or word }
- else if (l=2) and ((datasize and 1)<>0) then
- inc(datasize)
- end;
- pvarsym(sym)^.address:=datasize;
- inc(datasize,l);
-
- { this symbol can't be loaded to a register }
- pvarsym(sym)^.regable:=false;
- end
- else if symtabletype=parasymtable then
- begin
- pvarsym(sym)^.address:=datasize;
-
- { intel processors don't know a byte push, }
- { so is always a word pushed }
- if l=1 then
- l:=2;
- inc(datasize,l);
- end
- else
- begin
- if (l>=4) and ((datasize and 3)<>0) then
- inc(datasize,4-(datasize and 3))
- else if (l>=2) and ((datasize and 1)<>0) then
- inc(datasize,2-(datasize and 1));
- pvarsym(sym)^.address:=datasize;
- inc(datasize,l);
- end;
- end
- else if sym^.typ=typedconstsym then
- begin
- {$ifdef MAKELIB}
- bsssegment^.concat(new(pai_cut,init));
- {$endif MAKELIB}
- if symtabletype=globalsymtable then
- begin
- {$ifdef GDB}
- if cs_debuginfo in aktswitches then
- sym^.concatstabto(datasegment);
- {$endif GDB}
- datasegment^.concat(new(pai_symbol,init_global(sym^.mangledname)));
- end
- else
- if symtabletype<>unitsymtable then
- begin
- {$ifdef GDB}
- if cs_debuginfo in aktswitches then
- sym^.concatstabto(datasegment);
- {$endif GDB}
- {$ifndef MAKELIB}
- datasegment^.concat(new(pai_symbol,init(sym^.mangledname)));
- {$else MAKELIB}
- { we need to change this to a global symbol }
- { lets use almost the same prefix than for globals but with one $ more }
- datasegment^.concat(new(pai_symbol,init_global(sym^.mangledname)));
- {$endif MAKELIB}
- end;
- end;
- if (symtabletype=staticsymtable) or
- (symtabletype=globalsymtable) then
- begin
- hp:=symtablestack;
- while assigned(hp) do
- begin
- if hp^.symtabletype in
- [staticsymtable,globalsymtable] then
- begin
- hsym:=hp^.search(sym^.name);
- if (assigned(hsym)) and
- (hsym^.properties and sp_forwarddef=0) then
- Message1(sym_e_duplicate_id,sym^.name);
- end;
- hp:=hp^.next;
- end;
- end;
- if sym^.typ = typesym then
- if assigned(ptypesym(sym)^.definition) then
- begin
- if not assigned(ptypesym(sym)^.definition^.owner) then
- registerdef(ptypesym(sym)^.definition);
- {$ifdef GDB}
- if (cs_debuginfo in aktswitches) and assigned(debuglist)
- and (symtabletype <> unitsymtable) then
- begin
- ptypesym(sym)^.isusedinstab := true;
- sym^.concatstabto(debuglist);
- end;
- {$endif GDB}
- end;
- {$ifdef TEST_FUNCRET}
- if sym^.typ=funcretsym then
- begin
- { allocate space in local if ret in acc or in fpu }
- if ret_in_acc(procinfo.retdef) or (procinfo.retdef^.deftype=floatdef) then
- begin
- l:=pfuncretsym(sym)^.funcretdef^.size;
- inc(datasize,l);
- {$ifdef m68k}
- { word alignment required for motorola }
- if (l=1) then
- inc(datasize,1)
- else
- {$endif}
- if (l>=4) and ((datasize and 3)<>0) then
- inc(datasize,4-(datasize and 3))
- else if (l>=2) and ((datasize and 1)<>0) then
- inc(datasize,2-(datasize and 1));
-
- pfuncretsym(sym)^.address:=datasize;
- end;
- end;
- {$endif TEST_FUNCRET}
- sym^.speedvalue:=getspeedvalue(sym^.name);
- if assigned(hasharray) then
- _insert(hasharray^[sym^.speedvalue mod hasharraysize])
- else
- _insert(wurzel);
- end;
-
- procedure unitsymbolused(p : psym);
-
- begin
- if p^.typ=unitsym then
- if (punitsym(p)^.refs=0) then
- comment(V_info,'Unit '+p^.name+' is not used');
- end;
-
- procedure tsymtable.allunitsused;
-
- begin
- {$ifdef tp}
- foreach(unitsymbolused);
- {$else}
- foreach(@unitsymbolused);
- {$endif}
- end;
-
- procedure varsymbolused(p : psym);
-
- begin
- if (p^.typ=varsym) and
- ((p^.owner^.symtabletype=parasymtable) or
- (p^.owner^.symtabletype=localsymtable) or
- (p^.owner^.symtabletype=staticsymtable))
- then
- { unused symbol should be reported only if no }
- { error is reported }
- { if the symbol is in a register it is used }
- if (pvarsym(p)^.refs=0) and
- (errorcount=0) and
- (pvarsym(p)^.reg=R_NO) then
- begin
- { if p^.owner^.symtabletype=parasymtable then
- exterror:=strpnew(' arg '+p^.name
- +' declared in line '+tostr(p^.line_no))
- else
- exterror:=strpnew(' local '+p^.name
- +' declared in line '+tostr(p^.line_no)); }
- Message2(sym_h_identifier_not_used,p^.name,tostr(p^.line_no));
- end;
- end;
-
- procedure tsymtable.allsymbolsused;
-
- begin
- {$ifdef tp}
- foreach(varsymbolused);
- {$else}
- foreach(@varsymbolused);
- {$endif}
- end;
-
- {$ifdef CHAINPROCSYMS}
- procedure chainprocsym(p : psym);
-
- var
- storesymtablestack : psymtable;
- begin
- if p^.typ=procsym then
- begin
- storesymtablestack:=symtablestack;
- symtablestack:=p^.owner^.next;
- while assigned(symtablestack) do
- begin
- { search for same procsym in other units }
- getsym(p^.name,false);
- if assigned(srsym) and (srsym^.typ=procsym) then
- begin
- pprocsym(p)^.nextprocsym:=pprocsym(srsym);
- symtablestack:=storesymtablestack;
- exit;
- end
- else if srsym=nil then
- symtablestack:=nil
- else
- symtablestack:=srsymtable^.next;
- end;
- symtablestack:=storesymtablestack;
- end;
- end;
-
- procedure tsymtable.chainprocsyms;
-
- begin
- {$ifdef tp}
- foreach(chainprocsym);
- {$else}
- foreach(@chainprocsym);
- {$endif}
- end;
- {$endif CHAINPROCSYMS}
-
- {$ifdef GDB}
-
- var l : paasmoutput;
-
- procedure concatstab(p : psym);
- begin
- if p^.typ <> procsym then
- p^.concatstabto(l);
- end;
-
- procedure concattypestab(p : psym);
- begin
- if p^.typ = typesym then
- begin
- p^.isstabwritten:=false;
- p^.concatstabto(l);
- end;
- end;
-
- procedure tsymtable.concatstabto(asmlist : paasmoutput);
- begin
- l := asmlist;
- {$ifdef tp}
- foreach(concatstab);
- {$else}
- foreach(@concatstab);
- {$endif}
- end;
-
- procedure tunitsymtable.concattypestabto(asmlist : paasmoutput);
- var prev_dbx_count : plongint;
- begin
- if is_stab_written then exit;
- if not assigned(name) then name := stringdup('Main_program');
- if symtabletype = unitsymtable then
- begin
- unitid:=current_module^.unitcount;
- inc(current_module^.unitcount);
- end;
- asmlist^.concat(new(pai_direct,init(strpnew('# Begin unit '+name^
- +' has index '+tostr(unitid)))));
- if use_dbx then
- begin
- if dbx_count_ok then
- begin
- asmlist^.insert(new(pai_direct,init(strpnew('# "repeated" unit '+name^
- +' has index '+tostr(unitid)))));
- do_count_dbx:=true;
- asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
- +tostr(N_EXCL)+',0,0,'+tostr(dbx_count)))));
- exit;
- end;
- prev_dbx_count := dbx_counter;
- dbx_counter := nil;
- if symtabletype = unitsymtable then
- asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
- +tostr(N_BINCL)+',0,0,0'))));
- dbx_counter := @dbx_count;
- end;
- l:=asmlist;
- {$ifdef tp}
- foreach(concattypestab);
- {$else}
- foreach(@concattypestab);
- {$endif}
- if use_dbx then
- begin
- dbx_counter := prev_dbx_count;
- do_count_dbx:=true;
- asmlist^.concat(new(pai_stabs,init(strpnew('"'+name^+'",'
- +tostr(N_EINCL)+',0,0,0'))));
- dbx_count_ok := true;
- end;
- asmlist^.concat(new(pai_direct,init(strpnew('# End unit '+name^
- +' has index '+tostr(unitid)))));
- is_stab_written:=true;
- end;
-
- procedure forcestabto(asmlist : paasmoutput; pd : pdef);
- begin
- if not pd^.isstabwritten then
- begin
- if assigned(pd^.sym) and (pd^.sym^.typ=typesym) then
- pd^.sym^.isusedinstab := true;
- pd^.concatstabto(asmlist);
- end;
- end;
-
- {$endif GDB}
-
- function tsymtable.search(const s : stringid) : psym;
-
- var
- hp : psym;
- speedvalue : longint;
-
- begin
- speedvalue:=getspeedvalue(s);
- if assigned(hasharray) then
- hp:=hasharray^[speedvalue mod hasharraysize]
- else
- hp:=wurzel;
- while assigned(hp) do
- begin
- if speedvalue>hp^.speedvalue then hp:=hp^.left
- else if speedvalue<hp^.speedvalue then hp:=hp^.right
- else
- begin
- if (hp^.name=s) then
- begin
- { reject non static members in static procedures }
- if (symtabletype=objectsymtable) and
- ((hp^.properties and sp_static)=0) and
- assigned(aktprocsym) and
- ((aktprocsym^.definition^.options and postaticmethod)<>0) then
- Message(sym_e_only_static_in_static);
- { should we allow use of private field in the whole
- unit ? }
- if (symtabletype=objectsymtable) and
- (hp^.properties=sp_private) and
- {defowner is the objectdef and the owner of the objectdef
- is a unitsymtable, or golbalsymtable if we are compiling it !!}
- (psymtable(defowner^.owner)^.symtabletype<>globalsymtable) and
- (aktobjectdef<>pobjectdef(defowner)) and
- ((aktprocsym^.definition=nil) or
- (aktprocsym^.definition^._class<>pobjectdef(defowner))) then
- begin
- search:=nil;
- exit;
- end;
- search:=hp;
- if (symtabletype=unitsymtable) and
- assigned(punitsymtable(@self)^.unitsym) then
- inc(punitsymtable(@self)^.unitsym^.refs);
- {$ifdef UseBrowser}
- add_new_ref(hp^.lastref);
- { for symbols that are in tables without
- browser info }
- if hp^.refcount=0 then
- hp^.defref:=hp^.lastref;
- inc(hp^.refcount);
- {$endif UseBrowser}
- exit;
- end
- else if s>hp^.name then hp:=hp^.left
- else hp:=hp^.right;
- end;
- end;
- search:=nil;
- end;
-
- procedure tsymtable.foreach(proc2call : tcallback);
-
- procedure a(p : psym);
-
- { must be preorder, because it's used by reading in }
- { a PPU file }
- begin
- proc2call(p);
- if assigned(p^.left) then a(p^.left);
- if assigned(p^.right) then a(p^.right);
- end;
-
- var
- i : integer;
-
- begin
- if hasharray<>nil then
- begin
- for i:=0 to hasharraysize-1 do
- if assigned(hasharray^[i]) then
- a(hasharray^[i]);
- end
- else
- if assigned(wurzel) then
- a(wurzel);
- end;
-
- { write one symbol, is only used as call back procedure }
- procedure writesym(p : psym);
-
- begin
- p^.write;
- end;
-
- procedure tsymtable.number_units;
-
- var
- counter : word;
- p : psymtable;
-
- begin
- unitid:=0;
-
- { zuerst alle im Interface-Abschnitt aufgefhrten Units }
- { in die Datei schreiben und numerieren }
- p:=next;
- counter:=1;
-
- { im Implementationsteil aufgefuehrte Units ueberspringen }
- if symtabletype<>globalsymtable then
- begin
- while (p^.symtabletype<>globalsymtable) do
- p:=p^.next;
- p:=p^.next;
- end;
- while assigned(p) do
- begin
- if p^.symtabletype=unitsymtable then
- begin
- p^.unitid:=counter;
- inc(counter);
- end;
- p:=p^.next;
- end;
-
- end;
-
- procedure tsymtable.number_defs;
-
- var
- pd : pdef;
- counter : longint;
-
- begin
- counter:=0;
- pd:=wurzeldef;
- while assigned(pd) do
- begin
- pd^.number:=counter;
- inc(counter);
- pd:=pd^.next;
- end;
- end;
-
- {$ifdef GDB }
- procedure tunitsymtable.orderdefs;
- var
- first, last, nonum, pd, cur, prev, lnext : pdef;
-
- begin
- pd:=wurzeldef;
- first:=nil;
- last:=nil;
- nonum:=nil;
- while assigned(pd) do
- begin
- lnext:=pd^.next;
- if pd^.globalnb > 0 then
- if first = nil then
- begin
- first:=pd;
- last:=pd;
- last^.next:=nil;
- end
- else
- begin
- cur:=first;
- prev:=nil;
- while assigned(cur) and
- (prev <> last) and
- (cur^.globalnb>0) and
- (cur^.globalnb<pd^.globalnb) do
- begin
- prev:=cur;
- cur:=cur^.next;
- end;
- if cur = first then
- begin
- pd^.next:=first;
- first:=pd;
- end
- else
- if prev = last then
- begin
- pd^.next:=nil;
- last^.next:=pd;
- last:=pd;
- end
- else
- begin
- pd^.next:=cur;
- prev^.next:=pd;
- end;
- end
- else { without number }
- begin
- pd^.next:=nonum;
- nonum:=pd;
- end;
- pd:=lnext;
- end;
- if assigned(first) then
- begin
- wurzeldef:=first;
- last^.next:=nonum;
- end else
- wurzeldef:=nonum;
- end;
- {$endif GDB }
-
- procedure tunitsymtable.writeasunit;
-
- var
- counter : word;
- hp : pused_unit;
- hp2 : pextfile;
- s : string;
- index : word;
-
- begin
- { second write the used source files }
- hp2:=current_module^.sourcefiles.files;
- index:=current_module^.sourcefiles.last_ref_index;
- while assigned(hp2) do
- begin
- ppufile.write_byte(ibsourcefile);
-
- { only name and extension }
- writestring(hp2^.name^+hp2^.ext^);
- { index in that order }
- hp2^.ref_index:=index;
- dec(index);
- hp2:=hp2^._next;
- end;
-
- ppufile.write_byte(ibend);
-
- unitid:=0;
-
- { each used unit gets a number }
- counter:=1;
-
- { ... and write interface units with their number and checksum }
- hp:=pused_unit(current_module^.used_units.first);
- while assigned(hp) do
- begin
- if hp^.in_interface then
- begin
- psymtable(hp^.u^.symtable)^.unitid:=counter;
- inc(counter);
- ppufile.write_byte(ibloadunit);
- writestring(psymtable(hp^.u^.symtable)^.name^);
- ppufile.write_long(hp^.u^.crc);
- end;
- hp:=pused_unit(hp^.next);
- end;
-
- ppufile.write_byte(ibend);
-
- { writes the names of the units which should be init'ed
- s:=usedunits^.get;
- while s<>'' do
- begin
- writebyte(ibinitunit);
- writestring(s);
- s:=usedunits^.get;
- end;
- }
-
- { we should only write the objectfiles that come for this unit !! }
- while not current_module^.linkofiles.empty do
- begin
- ppufile.write_byte(iblinkofile);
- writestring(current_module^.linkofiles.get);
- end;
-
-
- { write any used libraries }
- while not current_module^.linklibfiles.empty do
- begin
- ppufile.write_byte(iblibraries);
- writestring(current_module^.linklibfiles.get);
- end;
-
-
- tsymtable.write;
- if use_dbx then
- begin
- ppufile.write_byte(ibdbxcount);
- ppufile.write_long(dbx_count);
- {$IfDef EXTDEBUG}
- writeln('Writing dbx_count ',dbx_count,' in unit ',name^,'.ppu');
- {$ENDIF EXTDEBUG}
- ppufile.write_byte(ibend);
- end;
- { ... and write implementation units with their number and checksum }
- hp:=pused_unit(current_module^.used_units.first);
- while assigned(hp) do
- begin
- if not hp^.in_interface then
- begin
- psymtable(hp^.u^.symtable)^.unitid:=counter;
- inc(counter);
- ppufile.write_byte(ibloadunit);
- writestring(psymtable(hp^.u^.symtable)^.name^);
- {this remains a problem : the crc is not calculted yet ! }
- ppufile.write_long(hp^.u^.crc);
- end;
- hp:=pused_unit(hp^.next);
- end;
-
- ppufile.write_byte(ibend);
-
- end;
-
- procedure tsymtable.writeasstruct;
-
- begin
- tsymtable.write;
- end;
-
- procedure tsymtable.write;
-
- var
- pd : pdef;
-
- begin
- { each definition get a number ... }
- number_defs;
- { ...now write the definition }
- pd:=wurzeldef;
- while assigned(pd) do
- begin
- pd^.write;
- pd:=pd^.next;
- end;
-
- { the next part are the symbols }
- ppufile.write_byte(ibend);
-
- { symbol numbering for references }
- {$ifdef UseBrowser}
- number_symbols;
- {$endif UseBrowser}
- { foreach is used to write all symbols }
-
- {$ifdef tp}
- foreach(writesym);
- {$else}
- foreach(@writesym);
- {$endif}
- { end of symbols }
- ppufile.write_byte(ibend);
- end;
-
- {**************************************
- "forward"-pointer
- **************************************}
-
- type
- presolvelist = ^tresolvelist;
-
- tresolvelist = record
- p : ppointerdef;
- typ : ptypesym;
- next : presolvelist;
- end;
-
- var
- swurzel : presolvelist;
-
- {$ifdef GDB}
- procedure clear_forwards;
-
- var
- p : presolvelist;
-
- begin
- p:=swurzel;
- while assigned(p) do
- begin
- swurzel:=p^.next;
- dispose(p);
- p := swurzel;
- end;
- end;
-
- {$endif GDB}
- procedure save_forward(ppd : ppointerdef;typesym : ptypesym);
-
- var
- p : presolvelist;
-
- begin
- new(p);
- p^.next:=swurzel;
- p^.p:=ppd;
- ppd^.defsym := typesym;
- p^.typ:=typesym;
- swurzel:=p;
- end;
-
- procedure resolve_forwards;
-
- var
- p : presolvelist;
-
- begin
- p:=swurzel;
- while p<>nil do
- begin
- swurzel:=swurzel^.next;
- p^.p^.definition:=p^.typ^.definition;
- dispose(p);
- p:=swurzel;
- end;
- end;
-
- constructor tsym.init(const n : string);
-
- begin
- left:=nil;
- right:=nil;
- setname(n);
- typ:=abstractsym;
- properties:=current_object_option;
- {$ifdef GDB}
- isstabwritten := false;
- if assigned(current_module) and assigned(current_module^.current_inputfile) then
- line_no:=current_module^.current_inputfile^.line_no
- else
- line_no:=0;
- {$endif GDB}
- {$ifdef UseBrowser}
- defref:=nil;
- lastwritten:=nil;
- add_new_ref(defref);
- lastref:=defref;
- refcount:=1;
- {$endif UseBrowser}
- end;
-
- constructor tsym.load;
-
- begin
- left:=nil;
- right:=nil;
- setname(readstring);
- typ:=abstractsym;
- if object_options then
- properties:=symprop(readbyte)
- else
- properties:=sp_public;
- {$ifdef UseBrowser}
- lastref:=nil;
- defref:=nil;
- lastwritten:=nil;
- refcount:=0;
- if (current_module^.flags and uf_uses_browser)<>0 then
- { references do not change the ppu caracteristics }
- { this only save the references to variables/functions }
- { defined in the unit what about the others }
- load_references;
- {$endif UseBrowser}
- {$ifdef GDB}
- isstabwritten := false;
- line_no:=0;
- {$endif GDB}
- end;
-
- {$ifdef UseBrowser}
- procedure tsym.load_references;
-
- var fileindex : word;
- b : byte;
- l : longint;
-
- begin
- b:=readbyte;
- while b=ibref do
- begin
- fileindex:=readword;
- l:=readlong;
- inc(refcount);
- lastref:=new(pref,load(lastref,fileindex,l));
- if refcount=1 then defref:=lastref;
- b:=readbyte;
- end;
- lastwritten:=lastref;
- if b <> ibend then
- Message(unit_f_ppu_read_error);
- end;
-
- procedure load_external_references;
-
- var b : byte;
- sym : psym;
- prdef : pdef;
- begin
- b:=readbyte;
- while (b=ibextsymref) or (b=ibextdefref) do
- begin
- if b=ibextsymref then
- begin
- sym:=readsymref;
- resolvesym(sym);
- sym^.load_references;
- b:=readbyte;
- end
- else
- if b=ibextdefref then
- begin
- prdef:=readdefref;
- resolvedef(prdef);
- if prdef^.deftype<>procdef then
- Message(unit_f_ppu_read_error);
- pprocdef(prdef)^.load_references;
- b:=readbyte;
- end;
- end;
- if b <> ibend then
- Message(unit_f_ppu_read_error);
- end;
-
- procedure tsym.write_references;
-
- var ref : pref;
-
- begin
- { references do not change the ppu caracteristics }
- { this only save the references to variables/functions }
- { defined in the unit what about the others }
- ppufile.do_crc:=false;
- if assigned(lastwritten) then
- ref:=lastwritten
- else
- ref:=defref;
- while assigned(ref) do
- begin
- if assigned(ref^.inputfile) then
- begin
- writebyte(ibref);
- writeword(ref^.inputfile^.ref_index);
- writelong(ref^.lineno);
- end;
- ref:=ref^.nextref;
- end;
- lastwritten:=lastref;
- writebyte(ibend);
- ppufile.do_crc:=true;
- end;
-
- procedure tsym.write_external_references;
-
- var ref : pref;
- prdef : pdef;
- begin
- ppufile.do_crc:=false;
- if lastwritten=lastref then exit;
- writebyte(ibextsymref);
- writesymref(@self);
- if assigned(lastwritten) then
- ref:=lastwritten
- else
- ref:=defref;
- while assigned(ref) do
- begin
- if assigned(ref^.inputfile) then
- begin
- writebyte(ibref);
- writeword(ref^.inputfile^.ref_index);
- writelong(ref^.lineno);
- end;
- ref:=ref^.nextref;
- end;
- lastwritten:=lastref;
- writebyte(ibend);
- if typ=procsym then
- begin
- prdef:=pprocsym(@self)^.definition;
- while assigned(prdef) do
- begin
- pprocdef(prdef)^.write_external_references;
- prdef:=pprocdef(prdef)^.nextoverloaded;
- end;
- end;
- ppufile.do_crc:=true;
- end;
-
- procedure tsym.write_ref_to_file(var f : text);
-
- var ref : pref;
-
- begin
- ref:=defref;
- while assigned(ref) do
- begin
- writeln(f,ref^.get_file_line);
- ref:=ref^.nextref;
- end;
- end;
- {$endif UseBrowser}
-
- destructor tsym.done;
-
- begin
- {$ifdef tp}
- if not(use_big) then
- {$endif tp}
- strdispose(_name);
- if assigned(left) then dispose(left,done);
- if assigned(right) then dispose(right,done);
- end;
-
- procedure tsym.write;
-
- begin
- writestring(name);
- if object_options then
- ppufile.write_byte(byte(properties));
- {$ifdef UseBrowser}
- if (current_module^.flags and uf_uses_browser)<>0 then
- write_references;
- {$endif UseBrowser}
- end;
-
- procedure tsym.deref;
-
- begin
- end;
-
- function tsym.name : string;
-
- {$ifdef tp}
- var
- s : string;
- b : byte;
-
- {$endif tp}
- begin
- {$ifdef tp}
- if use_big then
- begin
- symbolstream.seek(longint(_name));
- symbolstream.read(b,1);
- symbolstream.read(s[1],b);
- s[0]:=chr(b);
- name:=s;
- end
- else
- {$endif}
- begin
- name:=strpas(_name);
- end;
- end;
-
- function tsym.mangledname : string;
-
- begin
- mangledname:=name;
- end;
-
- procedure tsym.setname(const s : string);
-
- begin
- setstring(_name,s);
- end;
-
- {$ifdef GDB}
- function tsym.stabstring : pchar;
-
- begin
- stabstring:=strpnew('"'+name+'",'+tostr(N_LSYM)+',0,'+tostr(line_no)+',0');
- end;
-
- procedure tsym.concatstabto(asmlist : paasmoutput);
-
- var stab_str : pchar;
- begin
- if not isstabwritten then
- begin
- stab_str := stabstring;
- if asmlist = debuglist then do_count_dbx := true;
- { count_dbx(stab_str); moved to GDB.PAS }
- asmlist^.concat(new(pai_stabs,init(stab_str)));
- isstabwritten:=true;
- end;
- end;
- {$endif GDB}
-
- {**************************************
- TLABELSYM
- **************************************}
-
- constructor tlabelsym.init(const n : string; l : plabel);
-
- begin
- inherited init(n);
- typ:=labelsym;
- number:=l;
- number^.is_used:=false;
- number^.is_set:=true;
- number^.refcount:=0;
- defined:=false;
- end;
-
- destructor tlabelsym.done;
-
- begin
- if not(defined) then
- Message1(sym_e_label_not_defined,name);
- inherited done;
- end;
-
- function tlabelsym.mangledname : string;
-
- begin
- { this also sets the is_used field }
- mangledname:=lab2str(number);
- end;
-
- procedure tlabelsym.write;
-
- begin
- Message(sym_e_ill_label_decl);
- end;
-
- {**************************************
- TUNITSYM
- **************************************}
-
- constructor tunitsym.init(const n : string;ref : punitsymtable);
-
- begin
- tsym.init(n);
- typ:=unitsym;
- unitsymtable:=ref;
- prevsym:=ref^.unitsym;
- ref^.unitsym:=@self;
- refs:=0;
- end;
-
- destructor tunitsym.done;
- begin
- if assigned(unitsymtable) and (unitsymtable^.unitsym=@self) then
- unitsymtable^.unitsym:=prevsym;
- inherited done;
- end;
- procedure tunitsym.write;
-
- begin
- end;
-
- {$ifdef GDB}
- procedure tunitsym.concatstabto(asmlist : paasmoutput);
- begin
- {Nothing to write to stabs !}
- end;
-
- {$endif GDB}
-
- {**************************************
- TERRORSYM
- **************************************}
-
- constructor terrorsym.init;
-
- begin
- tsym.init('');
- typ:=errorsym;
- end;
-
- {**************************************
- TPROPERTYSYM
- **************************************}
-
- constructor tpropertysym.init(const n : string);
-
- begin
- inherited init(n);
- typ:=propertysym;
- options:=0;
- proptype:=nil;
- readaccessdef:=nil;
- writeaccessdef:=nil;
- readaccesssym:=nil;
- writeaccesssym:=nil;
- index:=$0;
- end;
-
- destructor tpropertysym.done;
-
- begin
- inherited done;
- end;
-
- constructor tpropertysym.load;
-
- begin
- inherited load;
- typ:=propertysym;
- proptype:=readdefref;
- options:=readlong;
- index:=readlong;
- { it's hack ... }
- readaccesssym:=psym(stringdup(readstring));
- writeaccesssym:=psym(stringdup(readstring));
- { now the defs: }
- readaccessdef:=readdefref;
- writeaccessdef:=readdefref;
- end;
-
- procedure tpropertysym.deref;
-
- begin
- resolvedef(proptype);
- resolvedef(readaccessdef);
- resolvedef(writeaccessdef);
- { solve the hack we did in load: }
- if pstring(readaccesssym)^<>'' then
- begin
- srsym:=search_class_member(pobjectdef(owner^.defowner),pstring(readaccesssym)^);
- if not(assigned(srsym)) then
- srsym:=generrorsym;
- end
- else
- srsym:=nil;
- stringdispose(pstring(readaccesssym));
- readaccesssym:=srsym;
- if pstring(writeaccesssym)^<>'' then
- begin
- srsym:=search_class_member(pobjectdef(owner^.defowner),pstring(writeaccesssym)^);
- if not(assigned(srsym)) then
- srsym:=generrorsym;
- end
- else
- srsym:=nil;
- stringdispose(pstring(writeaccesssym));
- writeaccesssym:=srsym;
- end;
-
- function tpropertysym.getsize : longint;
-
- begin
- getsize:=0;
- end;
-
- procedure tpropertysym.write;
-
- begin
- ppufile.write_byte(ibpropertysym);
- tsym.write;
- writedefref(proptype);
- ppufile.write_long(options);
- ppufile.write_long(index);
- writestring(readaccesssym^.name);
- writestring(writeaccesssym^.name);
- writedefref(readaccessdef);
- writedefref(writeaccessdef);
- end;
-
- {$ifdef GDB}
- function tpropertysym.stabstring : pchar;
-
- begin
- { !!!! don't know how to handle }
- stabstring:=strpnew('');
- end;
-
- procedure tpropertysym.concatstabto(asmlist : paasmoutput);
-
- begin
- { !!!! don't know how to handle }
- end;
- {$endif GDB}
-
- {$ifdef TEST_FUNCRET}
- {**************************************
- TFUNCRETSYM
- **************************************}
- constructor tfuncretsym.init(const n : string;approcinfo : pprocinfo);
-
- begin
- tsym.init(n);
- funcretprocinfo:=approcinfo;
- funcretdef:=approcinfo^.retdef;
- { address valid for ret in param only }
- { otherwise set by insert }
- address:=approcinfo^.retoffset;
- end;
- {$endif TEST_FUNCRET}
-
- {**************************************
- TABSOLUTESYM
- **************************************}
-
- { constructor tabsolutesym.init(const s : string;p : pdef;newref : psym);
- begin
- inherited init(s,p);
- ref:=newref;
- typ:=absolutesym;
- end; }
-
- constructor tabsolutesym.load;
-
- begin
- tvarsym.load;
- typ:=absolutesym;
- ref:=nil;
- address:=0;
- asmname:=nil;
- abstyp:=absolutetyp(readbyte);
- absseg:=false;
- case abstyp of
- tovar:
- begin
- asmname:=stringdup(readstring);
- ref:=srsym;
- end;
- toasm:
- asmname:=stringdup(readstring);
- toaddr:
- address:=readlong;
- end;
- end;
-
- procedure tabsolutesym.write;
-
- begin
- ppufile.write_byte(ibabsolutesym);
- tsym.write;
- ppufile.write_byte(byte(varspez));
- if read_member then
- ppufile.write_long(address);
- writedefref(definition);
- ppufile.write_byte(byte(abstyp));
- case abstyp of
- tovar:
- writestring(ref^.name);
- toasm:
- writestring(asmname^);
- toaddr:
- ppufile.write_long(address);
- end;
- end;
-
- procedure tabsolutesym.deref;
-
- begin
- resolvedef(definition);
- if (abstyp=tovar) and (asmname<>nil) then
- begin
- { search previous loaded symtables }
- getsym(asmname^,false);
- if not(assigned(srsym)) then
- getsymonlyin(owner,asmname^);
- if not(assigned(srsym)) then
- srsym:=generrorsym;
- ref:=srsym;
- stringdispose(asmname);
- end;
- end;
-
- function tabsolutesym.mangledname : string;
-
- begin
- case abstyp of
- tovar:
- mangledname:=ref^.mangledname;
- toasm:
- mangledname:=asmname^;
- toaddr:
- mangledname:='$'+tostr(address);
- else
- internalerror(10002);
- end;
- end;
-
- {$ifdef GDB}
- procedure tabsolutesym.concatstabto(asmlist : paasmoutput);
-
- begin
- { I don't know how to handle this !! }
- end;
-
- {$endif GDB}
- {**************************************
- TVARSYM
- **************************************}
-
- constructor tvarsym.init(const n : string;p : pdef);
-
- begin
- tsym.init(n);
- typ:=varsym;
- definition:=p;
- varspez:=vs_value;
- address:=0;
- refs:=0;
- is_valid := 1;
- { can we load the value into a register ? }
- case p^.deftype of
- pointerdef,enumdef,procvardef : regable:=true;
- orddef : case porddef(p)^.typ of
- u8bit,s32bit,bool8bit,uchar,
- s8bit,s16bit,u16bit,u32bit : regable:=true;
- else regable:=false;
- end;
- else regable:=false;
- end;
- reg:=R_NO;
- end;
-
- constructor tvarsym.load;
-
- begin
- tsym.load;
- typ:=varsym;
- varspez:=tvarspez(readbyte);
- if read_member then
- address:=readlong
- else address:=0;
- definition:=readdefref;
- refs := 0;
- is_valid := 1;
- { symbols which are load are never candidates for a register }
- regable:=false;
- reg:=R_NO;
- end;
-
- procedure tvarsym.deref;
-
- begin
- resolvedef(definition);
- end;
-
- procedure tvarsym.write;
-
- begin
- ppufile.write_byte(ibvarsym);
- tsym.write;
- ppufile.write_byte(byte(varspez));
-
- if read_member then
- ppufile.write_long(address);
-
- writedefref(definition);
- end;
-
- function tvarsym.mangledname : string;
-
- var prefix : string;
- begin
- case owner^.symtabletype of
- {$ifndef MAKELIB}
- staticsymtable : prefix:='_';
- {$else MAKELIB}
- staticsymtable : prefix:='_'+owner^.name^+'$$$_';
- {$endif MAKELIB}
- unitsymtable,globalsymtable : prefix:='U_'+owner^.name^+'_';
- else
- begin
- { static data filed are converted in parser.pas to
- a global variable }
- Message(sym_e_invalid_call_tvarsymmangledname);
- end;
- end;
- mangledname:=prefix+name;
- end;
-
- {$ifdef GDB}
- function tvarsym.stabstring : pchar;
-
- var st : char;
-
- begin
- if (owner^.symtabletype = objectsymtable) and
- ((properties and sp_static)<>0) then
- begin
- if use_gsym then st := 'G' else st := 'S';
- stabstring := strpnew('"'+owner^.name^+'__'+name+':'+
- +definition^.numberstring+'",'+
- tostr(N_LCSYM)+',0,'+tostr(line_no)+','+mangledname);
- end
- else if (owner^.symtabletype = globalsymtable) or
- (owner^.symtabletype = unitsymtable) then
- begin
- { Here we used S instead of
- because with G GDB doesn't look at the address field
- but searches the same name or with a leading underscore
- but these names don't exist in pascal !}
- if use_gsym then st := 'G' else st := 'S';
- stabstring := strpnew('"'+name+':'+st
- +definition^.numberstring+'",'+
- tostr(N_LCSYM)+',0,'+tostr(line_no)+','+mangledname);
- end
- else if owner^.symtabletype = staticsymtable then
- begin
- stabstring := strpnew('"'+name+':S'
- +definition^.numberstring+'",'+
- tostr(N_LCSYM)+',0,'+tostr(line_no)+','+mangledname);
- end
- else if (owner^.symtabletype=parasymtable) then
- begin
- case varspez of
- vs_value : st := 'p';
- vs_var : st := 'v';
- vs_const : st := 'v';{ should be 'i' but 'i' doesn't work }
- end;
- stabstring := strpnew('"'+name+':'+st
- +definition^.numberstring+'",'+
- tostr(N_PSYM)+',0,'+tostr(line_no)+','+tostr(address+owner^.call_offset))
- {offset to ebp => will not work if the framepointer is esp
- so some optimizing will make things harder to debug }
- end
- else if (owner^.symtabletype=localsymtable) then
- {$ifdef i386}
- if reg<>R_NO then
- begin
- { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
- { this is the register order for GDB }
- stabstring:=strpnew('"'+name+':r'
- +definition^.numberstring+'",'+
- tostr(N_RSYM)+',0,'+tostr(line_no)+','+tostr(GDB_i386index[reg]));
- end
- else
- {$endif i386}
- stabstring := strpnew('"'+name+':'
- +definition^.numberstring+'",'+
- tostr(N_LSYM)+',0,'+tostr(line_no)+',-'+tostr(address))
- else
- stabstring := inherited stabstring;
- end;
-
- procedure tvarsym.concatstabto(asmlist : paasmoutput);
- var stab_str : pchar;
- begin
- inherited concatstabto(asmlist);
- {$ifdef i386}
- if (owner^.symtabletype=parasymtable) and
- (reg<>R_NO) then
- begin
- { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
- { this is the register order for GDB }
- stab_str:=strpnew('"'+name+':r'
- +definition^.numberstring+'",'+
- tostr(N_RSYM)+',0,'+tostr(line_no)+','+tostr(GDB_i386index[reg]));
- asmlist^.concat(new(pai_stabs,init(stab_str)));
- end;
- {$endif i386}
- end;
-
- {$endif GDB}
- function tvarsym.getsize : longint;
-
- begin
- { only if the definition is set, we could determine the }
- { size, this is if an error occurs while reading the type }
- { also used for operator, this allows not to allocate the }
- { return size twice }
- if assigned(definition) then
- begin
- case varspez of
- vs_value : getsize:=definition^.size;
- vs_var : getsize:=4;
- vs_const : begin
- if (definition^.deftype=stringdef) or
- (definition^.deftype=arraydef) or
- (definition^.deftype=recorddef) or
- (definition^.deftype=objectdef) or
- (definition^.deftype=setdef) then
- getsize:=4
- else
- getsize:=definition^.size;
- end;
- end;
- end
- else
- getsize:=0;
- end;
-
- {**************************************
- TTYPEDCONSTSYM
- **************************************}
-
- constructor ttypedconstsym.init(const n : string;p : pdef);
-
- begin
- tsym.init(n);
- typ:=typedconstsym;
- definition:=p;
- prefix:=stringdup(procprefix);
- end;
-
- constructor ttypedconstsym.load;
-
- begin
- tsym.load;
- typ:=typedconstsym;
- definition:=readdefref;
- prefix:=stringdup(readstring);
- end;
-
- destructor ttypedconstsym.done;
-
- begin
- stringdispose(prefix);
- tsym.done;
- end;
-
- function ttypedconstsym.mangledname : string;
-
- begin
- mangledname:='TC_'+prefix^+'_'+name;
- end;
-
- procedure ttypedconstsym.deref;
-
- begin
- resolvedef(definition);
- end;
-
- procedure ttypedconstsym.write;
-
- begin
- ppufile.write_byte(ibtypedconstsym);
- tsym.write;
- writedefref(definition);
- writestring(prefix^);
- end;
-
- {$ifdef GDB}
- function ttypedconstsym.stabstring : pchar;
- var st : char;
- begin
- if use_gsym and ((owner^.symtabletype = unitsymtable)
- or (owner^.symtabletype = globalsymtable)) then
- st := 'G' else st := 'S';
- stabstring := strpnew('"'+name+':'+st
- +definition^.numberstring+'",'+tostr(n_STSYM)+',0,'+tostr(line_no)+','+mangledname);
- end;
- {$endif GDB}
-
- {**************************************
- TCONSTSYM
- **************************************}
-
- constructor tconstsym.init(const n : string;t : tconsttype;v : longint;def : pdef);
-
- begin
- tsym.init(n);
- typ:=constsym;
- definition:=def;
- consttype:=t;
- value:=v;
- end;
-
- constructor tconstsym.load;
-
- var
- pd : pdouble;
- ps : pointer; {***SETCONST}
-
- begin
- tsym.load;
- typ:=constsym;
- consttype:=tconsttype(readbyte);
- case consttype of
- constint,
- constbool,
- constchar : value:=readlong;
- constord : begin
- definition:=readdefref;
- value:=readlong;
- end;
- conststring : value:=longint(stringdup(readstring));
- constreal : begin
- new(pd);
- pd^:=readdouble;
- value:=longint(pd);
- end;
- {***SETCONST}
- constseta : begin
- getmem(ps,32);
- readset(ps^);
- value:=longint(ps);
- end;
- {***}
- else Message1(unit_f_ppu_invalid_entry,tostr(ord(consttype)));
- end;
- end;
-
- {$ifdef GDB}
- destructor tconstsym.done;
- begin
- if consttype = conststring then stringdispose(pstring(value));
- inherited done;
- end;
- {$endif GDB}
-
- function tconstsym.mangledname : string;
-
- begin
- mangledname:=name;
- end;
-
- procedure tconstsym.deref;
-
- begin
- if consttype=constord then
- resolvedef(pdef(definition));
- end;
-
- procedure tconstsym.write;
-
- begin
- ppufile.write_byte(ibconstsym);
- tsym.write;
- ppufile.write_byte(byte(consttype));
- case consttype of
- constint,
- constbool,
- constchar : ppufile.write_long(value);
- constord : begin
- writedefref(definition);
- ppufile.write_long(value);
- end;
- conststring : writestring(pstring(value)^);
- constreal : ppufile.write_double(pdouble(value)^);
- {***SETCONST}
- constseta: writeset(pointer(value)^);
- {***}
- else internalerror(13);
- end;
- end;
-
- {$ifdef GDB}
- function tconstsym.stabstring : pchar;
- var st : string;
- begin
- {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
- case consttype of
- conststring : begin
- { I had to remove ibm2ascii !! }
- st := pstring(value)^;
- {st := ibm2ascii(pstring(value)^);}
- st := 's'''+st+'''';
- end;
- constbool, constint, constord, constchar : st := 'i'+tostr(value);
- constreal : begin
- system.str(pdouble(value)^,st);
- st := 'r'+st;
- end;
- { if we don't know just put zero !! }
- else st:='i0';
- {***SETCONST}
- {constset:;} {*** I don't know what to do with a set.}
- { sets are not recognized by GDB }
- {***}
- end;
- stabstring := strpnew('"'+name+':c='+st+'",'+tostr(N_function)+',0,'+tostr(line_no)+',0');
- end;
-
- procedure tconstsym.concatstabto(asmlist : paasmoutput);
-
- begin
- if consttype <> conststring then inherited concatstabto(asmlist);
- end;
-
- {$endif GDB}
-
- {**************************************
- tenumsym
- **************************************}
-
- constructor tenumsym.init(const n : string;def : penumdef;v : longint);
- begin
- tsym.init(n);
- typ:=enumsym;
- definition:=def;
- value:=v;
- {$ifdef GDB}
- order;
- {$endif GDB}
- end;
-
- constructor tenumsym.load;
-
- begin
- tsym.load;
- typ:=enumsym;
- definition:=penumdef(readdefref);
- value:=readlong;
- {$ifdef GDB}
- next := Nil;
- {$endif GDB}
- end;
-
- procedure tenumsym.deref;
-
- begin
- resolvedef(pdef(definition));
- {$ifdef GDB}
- order;
- {$endif}
- end;
-
- {$ifdef GDB}
- procedure tenumsym.order;
- var sym : penumsym;
- begin
- sym := definition^.first;
- if sym = nil then
- begin
- definition^.first := @self;
- next := nil;
- exit;
- end;
- {reorder the symbols in increasing value }
- if value < sym^.value then
- begin
- next := sym;
- definition^.first := @self;
- end else
- begin
- while (sym^.value <= value) and assigned(sym^.next) do
- sym := sym^.next;
- next := sym^.next;
- sym^.next := @self;
- end;
- end;
- {$endif GDB}
-
- procedure tenumsym.write;
-
- begin
- ppufile.write_byte(ibaufzaehlsym);
- tsym.write;
- writedefref(definition);
- ppufile.write_long(value);
- end;
-
- {$ifdef GDB}
- procedure tenumsym.concatstabto(asmlist : paasmoutput);
- begin
- {enum elements have no stab !}
- end;
- {$EndIf GDB}
-
- {**************************************
- TTYPESYM
- **************************************}
-
- constructor ttypesym.init(const n : string;d : pdef);
-
- begin
- tsym.init(n);
- typ:=typesym;
- definition:=d;
- forwardpointer:=nil;
- { this allows to link definitions with the type with declares }
- { them }
- if assigned(definition) then
- if definition^.sym=nil then
- definition^.sym:=@self;
- end;
-
- constructor ttypesym.load;
-
- begin
- tsym.load;
- typ:=typesym;
- forwardpointer:=nil;
- definition:=readdefref;
- end;
-
- destructor ttypesym.done;
-
- begin
- if assigned(definition) then
- if definition^.sym=@self then
- definition^.sym:=nil;
- inherited done;
- end;
-
- procedure ttypesym.deref;
-
- begin
- resolvedef(definition);
- if assigned(definition) then
- if definition^.sym=nil then
- definition^.sym:=@self;
- end;
-
- procedure ttypesym.write;
-
- begin
- ppufile.write_byte(ibtypesym);
- tsym.write;
- writedefref(definition);
- end;
-
- {$ifdef GDB}
- function ttypesym.stabstring : pchar;
- var stabchar : string[2];
- short : string;
- begin
- if definition^.deftype in tagtypes then
- stabchar := 'Tt'
- else stabchar := 't';
- short := '"'+name+':'+stabchar+definition^.numberstring
- +'",'+tostr(N_LSYM)+',0,'+tostr(line_no)+',0';
- stabstring := strpnew(short);
- end;
-
- procedure ttypesym.concatstabto(asmlist : paasmoutput);
- begin
- {not stabs for forward defs }
- if assigned(definition) then
- if (definition^.sym = @self) then
- definition^.concatstabto(asmlist)
- else
- begin
- inherited concatstabto(asmlist);
- end;
- end;
-
- {$endif GDB}
-
- {**************************************
- TPROCSYM
- **************************************}
-
- procedure tprocsym.write;
-
- begin
- ppufile.write_byte(ibprocsym);
- tsym.write;
- writedefref(pdef(definition));
- end;
-
- {$ifdef GDB}
- function tprocsym.stabstring : pchar;
- Var RetType : Char;
- Obj,Info : String;
- begin
- obj := name;
- info := '';
- if is_global then
- RetType := 'F'
- else
- RetType := 'f';
- if assigned(owner) then
- begin
- if (owner^.symtabletype = objectsymtable) then
- obj := owner^.name^+'__'+name;
- if (owner^.symtabletype=localsymtable) and assigned(owner^.name) then
- info := ','+name+','+owner^.name^;
- end;
- stabstring :=strpnew('"'+obj+':'+RetType
- +definition^.retdef^.numberstring+info+'",'+tostr(n_function)
- +',0,'+tostr(current_module^.current_inputfile^.line_no)
- +','+definition^.mangledname);
- end;
-
- procedure tprocsym.concatstabto(asmlist : paasmoutput);
- begin
- if (definition^.options and pointernproc) <> 0 then exit;
- if not isstabwritten then
- asmlist^.concat(new(pai_stabs,init(stabstring)));
- isstabwritten := true;
- if assigned(definition^.parast) then
- definition^.parast^.concatstabto(asmlist);
- if assigned(definition^.localst) then
- definition^.localst^.concatstabto(asmlist);
- definition^.isstabwritten := true;
- end;
-
- {$endif GDB}
- {**************************************
- TSYSSYM
- **************************************}
-
- constructor tsyssym.init(const n : string;l : longint);
-
- begin
- inherited init(n);
- typ:=syssym;
- number:=l;
- end;
-
- procedure tsyssym.write;
-
- begin
- end;
-
- {$ifdef GDB}
- procedure tsyssym.concatstabto(asmlist : paasmoutput);
-
- begin
- end;
-
- {$endif GDB}
- {**************************************
- TMACROSYM
- **************************************}
-
- constructor tmacrosym.init(const n : string);
-
- begin
- inherited init(n);
- defined:=true;
- buftext:=nil;
- buflen:=0;
- end;
-
- destructor tmacrosym.done;
-
- begin
- if assigned(buftext) then
- freemem(buftext,buflen);
- inherited done;
- end;
-
- procedure maybe_concat_external(symt : psymtable;const name : string);
-
- begin
- if (symt^.symtabletype=unitsymtable) or
- ((symt^.symtabletype=objectsymtable) and
- (symt^.defowner^.owner^.symtabletype=unitsymtable)) then
- concat_external(name,EXT_NEAR);
- end;
-
- function globaldef(const s : string) : pdef;
-
- var st : string;
- symt : psymtable;
- begin
- srsym := nil;
- if pos('.',s) > 0 then
- begin
- st := copy(s,1,pos('.',s)-1);
- getsym(st,false);
- st := copy(s,pos('.',s)+1,255);
- if assigned(srsym) then
- begin
- if srsym^.typ = unitsym then
- begin
- symt := punitsym(srsym)^.unitsymtable;
- srsym := symt^.search(st);
- end else srsym := nil;
- end;
- end else st := s;
- if srsym = nil then getsym(st,false);
- if srsym = nil then
- getsymonlyin(systemunit,st);
- if srsym^.typ<>typesym then
- begin
- Message(sym_e_type_id_expected);
- exit;
- end;
- globaldef := ptypesym(srsym)^.definition;
- end;
-
- {$ifdef GDB}
- function typeglobalnumber(const s : string) : string;
-
- var st : string;
- symt : psymtable;
- begin
- typeglobalnumber := '0';
- srsym := nil;
- if pos('.',s) > 0 then
- begin
- st := copy(s,1,pos('.',s)-1);
- getsym(st,false);
- st := copy(s,pos('.',s)+1,255);
- if assigned(srsym) then
- begin
- if srsym^.typ = unitsym then
- begin
- symt := punitsym(srsym)^.unitsymtable;
- srsym := symt^.search(st);
- end else srsym := nil;
- end;
- end else st := s;
- if srsym = nil then getsym(st,true);
- if srsym^.typ<>typesym then
- begin
- Message(sym_e_type_id_expected);
- exit;
- end;
- typeglobalnumber := ptypesym(srsym)^.definition^.numberstring;
- end;
- {$endif GDB}
-
- {**************************************
- TDEF
- **************************************}
-
-
- { base class for type definitions }
-
- constructor tdef.init;
-
- begin
- deftype:=abstractdef;
- {$ifdef GDB}
- owner := nil;
- next := nil;
- number := 0;
- globalnb := 0;
- {$endif GDB}
- if registerdef then symtablestack^.registerdef(@self);
- {$ifdef GDB}
- isstabwritten := false;
- if assigned(lastglobaldef) then
- lastglobaldef^.nextglobal := @self
- else firstglobaldef := @self;
- lastglobaldef := @self;
- nextglobal := nil;
- sym := nil;
- {$endif GDB}
- end;
-
- {$ifdef GDB}
- constructor tdef.load;
- begin
- deftype:=abstractdef;
- isstabwritten := false;
- number := 0;
- if assigned(lastglobaldef) then
- lastglobaldef^.nextglobal := @self
- else firstglobaldef := @self;
- lastglobaldef := @self;
- nextglobal := nil;
- sym := nil;
- owner := nil;
- next := nil;
- end;
-
- procedure tdef.set_globalnb;
- begin
- globalnb :=PGlobalTypeCount^;
- inc(PglobalTypeCount^);
- end;
- {$endif GDB}
- function tdef.size : longint;
-
- begin
- size:=savesize;
- end;
-
- procedure tdef.write;
-
- begin
- {$ifdef GDB }
- if globalnb = 0 then
- begin
- if assigned(owner) then
- globalnb := owner^.getnewtypecount
- else
- begin
- globalnb := PGlobalTypeCount^;
- Inc(PGlobalTypeCount^);
- end;
- end;
- {$endif GDB }
- end;
-
- {$ifdef GDB}
- function tdef.stabstring : pchar;
-
- begin
- stabstring := strpnew('t'+numberstring+';');
- end;
-
- function tdef.numberstring : string;
- var table : psymtable;
- begin
- {formal def have no type !}
- if deftype = formaldef then
- begin
- numberstring := voiddef^.numberstring;
- exit;
- end;
- if not assigned(sym) or not(sym^.isusedinstab) then
- begin
- {set even if debuglist is not defined}
- if assigned(sym) and (sym^.typ=typesym) then
- sym^.isusedinstab := true;
- if assigned(debuglist) and not isstabwritten then
- concatstabto(debuglist);
- end;
- if not use_dbx then
- begin
- if globalnb = 0 then
- set_globalnb;
- numberstring := tostr(globalnb);
- end
- else
- begin
- if globalnb = 0 then
- begin
- if assigned(owner) then
- globalnb := owner^.getnewtypecount
- else
- begin
- globalnb := PGlobalTypeCount^;
- Inc(PGlobalTypeCount^);
- end;
- end;
- if assigned(sym) then
- begin
- table := sym^.owner;
- if table^.unitid > 0 then
- numberstring := '('+tostr(table^.unitid)+','+tostr(sym^.definition^.globalnb)+')'
- else
- numberstring := tostr(globalnb);
- exit;
- end;
- numberstring := tostr(globalnb);
- end;
- end;
-
- function tdef.allstabstring : pchar;
- var stabchar : string[2];
- ss,st : pchar;
- name : string;
- sym_line_no : longint;
- begin
- ss := stabstring;
- getmem(st,strlen(ss)+512);
- stabchar := 't';
- if deftype in tagtypes then
- stabchar := 'Tt';
- if assigned(sym) then
- begin
- name := sym^.name;
- sym_line_no:=sym^.line_no;
- end
- else
- begin
- name := ' ';
- sym_line_no:=0;
- end;
- strpcopy(st,'"'+name+':'+stabchar+numberstring+'=');
- strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
- allstabstring := strnew(st);
- freemem(st,strlen(ss)+512);
- strdispose(ss);
- end;
-
-
- procedure tdef.concatstabto(asmlist : paasmoutput);
- var stab_str : pchar;
- begin
- if ((sym = nil) or sym^.isusedinstab or use_dbx)
- and not isstabwritten then
- begin
- If use_dbx then
- begin
- { otherwise you get two of each def }
- If assigned(sym) then
- begin
- if sym^.typ=typesym then
- sym^.isusedinstab:=true;
- if (sym^.owner = nil) or
- ((sym^.owner^.symtabletype = unitsymtable) and
- punitsymtable(sym^.owner)^.dbx_count_ok) then
- begin
- {with DBX we get the definition from the other objects }
- isstabwritten := true;
- exit;
- end;
- end;
- end;
- { to avoid infinite loops }
- isstabwritten := true;
- stab_str := allstabstring;
- if asmlist = debuglist then do_count_dbx := true;
- { count_dbx(stab_str); moved to GDB.PAS}
- asmlist^.concat(new(pai_stabs,init(stab_str)));
- end;
- end;
-
- {$endif GDB}
- procedure tdef.deref;
-
- begin
- end;
-
- destructor tdef.done;
- {$ifdef debug}
- var prev : pdef;
- {$endif debug}
-
- {$ifndef GDB}
-
- {$else GDB}
- var pd : pdef;
- begin
- pd := firstglobaldef;
- if pd = @self then firstglobaldef := pd^.nextglobal
- else while assigned(pd) do
- {$endif GDB}
- begin
- {$ifdef GDB}
- if pd^.nextglobal = @Self then
- begin
- pd^.nextglobal := pd^.nextglobal^.nextglobal;
- if pd^.nextglobal = nil then
- lastglobaldef := pd;
- break;
- end;
- {$ifdef debug}
- prev:=pd;
- {$endif debug}
- pd := pd^.nextglobal;
- end;
- {$endif GDB}
- end;
-
- {**************************************
- TSTRINGDEF
- **************************************}
-
- constructor tstringdef.init(l : byte);
-
- begin
- tdef.init;
- string_typ:=shortstring;
- deftype:=stringdef;
- len:=l;
- savesize:=len+1;
- end;
-
- constructor tstringdef.load;
-
- begin
- {$ifdef GDB}
- tdef.load;
- string_typ:=shortstring;
- set_globalnb;
- {$endif GDB}
- deftype:=stringdef;
- len:=readbyte;
- savesize:=len+1;
- end;
-
- {$ifdef UseLongString}
- constructor tstringdef.longinit(l : longint);
-
- begin
- tdef.init;
- string_typ:=longstring;
- deftype:=stringdef;
- len:=l;
- savesize:=len+5;
- end;
-
- constructor tstringdef.longload;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=stringdef;
- string_typ:=longstring;
- len:=readlong;
- savesize:=len+5;
- end;
- {$endif UseLongString}
-
- {$ifdef UseAnsiString}
- constructor tstringdef.ansiinit(l : longint);
-
- begin
- tdef.init;
- string_typ:=ansistring;
- deftype:=stringdef;
- len:=l;
- savesize:=len+13;
- end;
-
- constructor tstringdef.ansiload;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=stringdef;
- string_typ:=ansistring;
- len:=readlong;
- savesize:=len+13;
- end;
- {$endif UseAnsiString}
-
- function tstringdef.size : longint;
-
- begin
- size:=len+1;
- end;
-
- procedure tstringdef.write;
-
- begin
- case string_typ of
- shortstring : ppufile.write_byte(ibstringdef);
- {$ifdef UseLongString}
- longstring : ppufile.write_byte(iblongstringdef);
- {$endif UseLongString}
- {$ifdef UseAnsiString}
- ansistring : ppufile.write_byte(ibansistringdef);
- {$endif UseAnsiString}
- end;
- tdef.write;
- if string_typ=shortstring then
- ppufile.write_byte(len)
- else
- ppufile.write_long(len);
- end;
-
- {$ifdef GDB}
- function tstringdef.stabstring : pchar;
-
- var bytest,charst,longst : string;
-
- begin
- if string_typ=shortstring then
- begin
- charst := typeglobalnumber('char');
- { this is what I found in stabs.texinfo but
- gdb 4.12 for go32 doesn't understand that !! }
- {$IfDef GDBknowsstrings}
- stabstring := strpnew('n'+charst+';'+tostr(len));
- {$else}
- bytest := typeglobalnumber('byte');
- stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
- +',0,8;st:ar'+bytest
- +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
- {$EndIf}
- end
- {$ifdef UseLongString}
- else if string_typ=longstring then
- begin
- charst := typeglobalnumber('char');
- { this is what I found in stabs.texinfo but
- gdb 4.12 for go32 doesn't understand that !! }
- {$IfDef GDBknowsstrings}
- stabstring := strpnew('n'+charst+';'+tostr(len));
- {$else}
- bytest := typeglobalnumber('byte');
- longst := typeglobalnumber('longint');
- stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
- +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
- +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
- {$EndIf}
- end
- {$endif UseLongString}
- {$ifdef UseAnsiString}
- else if string_typ=ansistring then
- begin
- { an ansi string looks like a pchar easy !! }
- stabstring:=strpnew('*'+typeglobalnumber('char'));
- end
- {$endif UseAnsiString}
- end;
-
- procedure tstringdef.concatstabto(asmlist : paasmoutput);
- begin
- inherited concatstabto(asmlist);
- end;
- {$endif GDB}
-
- {**************************************
- tenumdef
- **************************************}
-
- constructor tenumdef.init;
-
- begin
- tdef.init;
- deftype:=enumdef;
- max:=0;
- savesize:=4;
- has_jumps:=false;
- {$ifdef GDB}
- first := Nil;
- {$endif GDB}
- end;
-
- constructor tenumdef.load;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=enumdef;
- max:=readlong;
- savesize:=4;
- has_jumps:=false;
- first := Nil;
- end;
-
- destructor tenumdef.done;
- begin
- inherited done;
- end;
-
- procedure tenumdef.write;
-
- begin
- ppufile.write_byte(ibenumdef);
- tdef.write;
- ppufile.write_long(max);
- {$ifdef GDB}
- end;
-
- function tenumdef.stabstring : pchar;
- var st,st2 : pchar;
- p : penumsym;
- s : string;
- memsize : word;
- begin
- memsize := memsizeinc;
- getmem(st,memsize);
- strpcopy(st,'e');
- p := first;
- while assigned(p) do
- begin
- s :=p^.name+':'+tostr(p^.value)+',';
- { place for the ending ';' also }
- if (strlen(st)+length(s)+1<memsize) then
- strpcopy(strend(st),s)
- else
- begin
- getmem(st2,memsize+memsizeinc);
- strcopy(st2,st);
- freemem(st,memsize);
- st := st2;
- memsize := memsize+memsizeinc;
- strpcopy(strend(st),s);
- end;
- p := p^.next;
- end;
- strpcopy(strend(st),';');
- stabstring := strnew(st);
- freemem(st,memsize);
- {$endif GDB}
- end;
-
- {**************************************
- TORDDEF
- **************************************}
-
- constructor torddef.init(t : tbasetype;v,b : longint);
-
- begin
- tdef.init;
- deftype:=orddef;
- von:=v;
- bis:=b;
- typ:=t;
- setsize;
- end;
-
- constructor torddef.load;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=orddef;
- typ:=tbasetype(readbyte);
- von:=readlong;
- bis:=readlong;
- rangenr:=0;
- setsize;
- end;
-
- procedure torddef.setsize;
-
- begin
- if typ=uauto then
- begin
- { generate a unsigned range if bis<0 and von>=0 }
- if (von>=0) and (bis<0) then
- begin
- savesize:=4;
- typ:=u32bit;
- end
- else if (von>=0) and (bis<=255) then
- begin
- savesize:=1;
- typ:=u8bit;
- end
- else if (von>=-128) and (bis<=127) then
- begin
- savesize:=1;
- typ:=s8bit;
- end
- else if (von>=0) and (bis<=65536) then
- begin
- savesize:=2;
- typ:=u16bit;
- end
- else if (von>=-32768) and (bis<=32767) then
- begin
- savesize:=2;
- typ:=s16bit;
- end
- else
- begin
- savesize:=4;
- typ:=s32bit;
- end;
- end
- else
- case typ of
- uchar,u8bit,bool8bit,s8bit : savesize:=1;
- u16bit,s16bit : savesize:=2;
- s32bit,u32bit : savesize:=4;
- else savesize:=0;
- end;
-
- { there are no entrys for range checking }
- rangenr:=0;
- end;
-
- procedure torddef.genrangecheck;
-
- var
- name : string;
-
- begin
- if rangenr=0 then
- begin
- { generate two constant for bounds }
- getlabelnr(rangenr);
- {$ifndef MAKELIB}
- name:='R_'+tostr(rangenr);
- {$else MAKELIB}
- name:='R_'+current_module^.mainsource^+tostr(rangenr);
- {$endif MAKELIB}
- { if we are in the interface on a unit this must be global }
- { and the name must be unique }
- {$ifndef MAKELIB}
- datasegment^.concat(new(pai_symbol,init(name)));
- {$else MAKELIB}
- datasegment^.concat(new(pai_symbol,init_global(name)));
- {$endif MAKELIB}
- if von<=bis then
- begin
- datasegment^.concat(new(pai_const,init_32bit(von)));
- datasegment^.concat(new(pai_const,init_32bit(bis)));
- end
- { for u32bit we need two bounds }
- else
- begin
- datasegment^.concat(new(pai_const,init_32bit(von)));
- datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
- inc(nextlabelnr);
- {$ifndef MAKELIB}
- name:='R_'+tostr(rangenr+1);
- {$else MAKELIB}
- name:='R_'+current_module^.unitname^+tostr(rangenr+1);
- {$endif MAKELIB}
- { if we are in the interface on a unit this must be global }
- { and the name must be unique }
- {$ifndef MAKELIB}
- datasegment^.concat(new(pai_symbol,init(name)));
- {$else MAKELIB}
- datasegment^.concat(new(pai_symbol,init_global(name)));
- {$endif MAKELIB}
- datasegment^.concat(new(pai_const,init_32bit($80000000)));
- datasegment^.concat(new(pai_const,init_32bit(bis)));
- end;
- end;
- end;
-
- procedure torddef.write;
-
- begin
- ppufile.write_byte(iborddef);
- tdef.write;
- ppufile.write_byte(byte(typ));
- ppufile.write_long(von);
- ppufile.write_long(bis);
- end;
-
- {$ifdef GDB}
- function torddef.stabstring : pchar;
-
- begin
- case typ of
- uvoid : stabstring := strpnew(numberstring+';');
- {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
- bool8bit : stabstring := strpnew('r'+numberstring+';0;255;');
- { u32bit : stabstring := strpnew('r'+
- s32bitdef^.numberstring+';0;-1;'); }
- else stabstring := strpnew('r'+s32bitdef^.numberstring+';'
- +tostr(von)+';'+tostr(bis)+';');
- end;
- end;
-
- {$endif GDB}
-
- {**************************************
- TFLOATDEF
- **************************************}
-
- constructor tfloatdef.init(t : tfloattype);
-
- begin
- tdef.init;
- deftype:=floatdef;
- typ:=t;
- setsize;
- end;
-
- constructor tfloatdef.load;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=floatdef;
- typ:=tfloattype(readbyte);
- setsize;
- end;
-
- procedure tfloatdef.setsize;
-
- begin
- case typ of
- f16bit:
- savesize:=2;
- f32bit,s32real:
- savesize:=4;
- s64real:
- savesize:=8;
- s64bit:
- savesize:=8;
- s80real:
- savesize:=extended_size;
- else savesize:=0;
- end;
- end;
-
- procedure tfloatdef.write;
-
- begin
- ppufile.write_byte(ibfloatdef);
- tdef.write;
- ppufile.write_byte(byte(typ));
- end;
-
- {$ifdef GDB}
- function tfloatdef.stabstring : pchar;
-
- begin
- case typ of
- s32real,
- s64real : stabstring := strpnew('r'+
- s32bitdef^.numberstring+';'+tostr(savesize)+';0;');
- { for fixed real use longint instead to be able to }
- { debug something at least }
- f32bit:
- stabstring := s32bitdef^.stabstring;
- f16bit:
- stabstring := strpnew('r'+s32bitdef^.numberstring+';0;'+
- tostr($ffff)+';');
- { found this solution in stabsread.c from GDB v4.16 }
- s64bit : stabstring := strpnew('r'+
- s32bitdef^.numberstring+';-'+tostr(savesize)+';0;');
- {$ifdef i386}
- { under dos at least you must give a size of twelve instead of 10 !! }
- { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
- s80real : stabstring := strpnew('r'+
- s32bitdef^.numberstring+';12;0;');
- {$endif i386}
- else
- internalerror(10005);
- end;
- end;
-
- {$endif GDB}
-
- {**************************************
- TFILEDEF
- **************************************}
-
- constructor tfiledef.init(ft : tfiletype;tas : pdef);
-
- begin
- inherited init;
- deftype:=filedef;
- filetype:=ft;
- typed_as:=tas;
- setsize;
- end;
-
- constructor tfiledef.load;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=filedef;
- filetype:=tfiletype(readbyte);
- if filetype=ft_typed then
- typed_as:=readdefref
- else
- typed_as:=nil;
- setsize;
- end;
-
- procedure tfiledef.deref;
-
- begin
- if filetype=ft_typed then
- resolvedef(typed_as);
- end;
-
- procedure tfiledef.write;
-
- begin
- ppufile.write_byte(ibfiledef);
- tdef.write;
- ppufile.write_byte(byte(filetype));
- if filetype=ft_typed then
- writedefref(typed_as);
- end;
-
- {$ifdef GDB}
- function tfiledef.stabstring : pchar;
-
- var namesize : longint;
- begin
- {$IfDef GDBknowsfiles}
- case filetyp of
- ft_typed : stabstring := strpnew('d'+typed_as^.numberstring{+';'});
- ft_untyped : stabstring := strpnew('d'+voiddef^.numberstring{+';'});
- ft_text : stabstring := strpnew('d'+cchardef^.numberstring{+';'});
- end;
- {$Else }
- {based on
- filerec = record
- handle : word;
- mode : word;
- recsize : word;
- _private : array[1..26] of byte;
- userdata : array[1..16] of byte;
- name : string[79 or 255 for linux]; }
- if target_info.target=target_LINUX then
- namesize:=255
- else
- namesize:=79;
-
- stabstring := strpnew('s'+tostr(savesize)+'HANDLE:'+typeglobalnumber('word')+',0,16;'+
- 'MODE:'+typeglobalnumber('word')+',16,16;'+
- 'RECSIZE:'+typeglobalnumber('word')+',32,16;'+
- '_PRIVATE:ar'+typeglobalnumber('word')+';1;26;'+typeglobalnumber('byte')+',36,208;'+
- 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')+',256,128;'+
- 'NAME:s'+tostr(namesize+1)+
- 'length:'+typeglobalnumber('byte')+',0,8;'+
- 'st:ar'+typeglobalnumber('word')+';1;'
- +tostr(namesize)+';'+typeglobalnumber('char')+',8,'+tostr(8*namesize)+';;'+
- ',384,'+tostr(8*(namesize+1))+';;');
- {$EndIf}
- end;
-
- procedure tfiledef.concatstabto(asmlist : paasmoutput);
-
- begin
- { most file defs are unnamed !!! }
- if ((sym = nil) or sym^.isusedinstab or use_dbx) and not isstabwritten then
- begin
- if assigned(typed_as) then forcestabto(asmlist,typed_as);
- inherited concatstabto(asmlist);
- end;
- end;
-
- {$endif GDB}
- procedure tfiledef.setsize;
-
- begin
- case target_info.target of
- target_LINUX:
- begin
- case filetype of
- ft_text : savesize:=432;
- ft_typed,ft_untyped : savesize:=304;
- end;
- end;
- target_Win32 , target_AMIGA, target_MAC68k:
- begin
- case filetype of
- ft_text : savesize:=434;
- ft_typed,ft_untyped : savesize:=306;
- end;
- end
- else
- begin { os/2, dos, atari tos }
- case filetype of
- ft_text : savesize:=256;
- ft_typed,ft_untyped : savesize:=128;
- end;
- end;
- end;
- end;
-
- {**************************************
- TPOINTERDEF
- **************************************}
-
- constructor tpointerdef.init(def : pdef);
-
- begin
- inherited init;
- deftype:=pointerdef;
- definition:=def;
- savesize:=4;
- end;
-
- constructor tpointerdef.load;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=pointerdef;
- { the real address in memory is calculated later (deref) }
- definition:=readdefref;
- savesize:=4;
- end;
-
- procedure tpointerdef.deref;
-
- begin
- resolvedef(definition);
- end;
-
- procedure tpointerdef.write;
-
- begin
- ppufile.write_byte(ibpointerdef);
- tdef.write;
- writedefref(definition);
- end;
-
- {$ifdef GDB}
- function tpointerdef.stabstring : pchar;
-
- begin
- stabstring := strpnew('*'+definition^.numberstring);
- end;
-
- procedure tpointerdef.concatstabto(asmlist : paasmoutput);
- var st,nb : string;
- sym_line_no : longint;
- begin
- if ( (sym=nil) or sym^.isusedinstab or use_dbx) and not isstabwritten then
- begin
- if assigned(definition) then
- if definition^.deftype in [recorddef,objectdef] then
- begin
- isstabwritten := true;
- {to avoid infinite recursion in record with next-like fields }
- nb := definition^.numberstring;
- isstabwritten := false;
- if not definition^.isstabwritten then
- begin
- if assigned(definition^.sym) then
- begin
- if assigned(sym) then
- begin
- st := sym^.name;
- sym_line_no:=sym^.line_no;
- end
- else
- begin
- st := ' ';
- sym_line_no:=0;
- end;
- st := '"'+st+':t'+numberstring+'=*'+definition^.numberstring
- +'=xs'+definition^.sym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
- if asmlist = debuglist then do_count_dbx := true;
- asmlist^.concat(new(pai_stabs,init(strpnew(st))));
- end;
- end else inherited concatstabto(asmlist);
- isstabwritten := true;
- end else
- begin
- forcestabto(asmlist,definition);
- inherited concatstabto(asmlist);
- end;
- end;
- end;
-
- {$endif GDB}
-
- {**************************************
- TCLASSREFDEF
- **************************************}
-
- constructor tclassrefdef.init(def : pdef);
-
- begin
- inherited init(def);
- deftype:=classrefdef;
- definition:=def;
- savesize:=4;
- end;
-
- constructor tclassrefdef.load;
-
- begin
- inherited load;
- deftype:=classrefdef;
- end;
-
- procedure tclassrefdef.write;
-
- begin
- ppufile.write_byte(ibclassrefdef);
- tdef.write;
- writedefref(definition);
- end;
-
- {$ifdef GDB}
- function tclassrefdef.stabstring : pchar;
-
- begin
- stabstring:=strpnew('');
- end;
-
- procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
-
- begin
- end;
-
- {$endif GDB}
-
- {**************************************
- TSETDEF
- **************************************}
-
- constructor tsetdef.init(s : pdef;high : longint);
-
- begin
- inherited init;
- deftype:=setdef;
- setof:=s;
- if high<32 then
- begin
- settype:=smallset;
- savesize:=4;
- end
- else
- if high<256 then
- begin
- settype:=normset;
- savesize:=32;
- end
- else
- {$ifdef testvarsets}
- if high<$10000 then
- begin
- settype:=varset;
- savesize:=4*((high+31) div 32);
- end
- else
- {$endif testvarsets}
- Message(sym_e_ill_type_decl_set);
- end;
-
- constructor tsetdef.load;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=setdef;
- setof:=readdefref;
- settype:=tsettype(readbyte);
- case settype of
- normset : savesize:=32;
- varset : savesize:=readlong;
- smallset : savesize:=4;
- end;
- end;
-
- procedure tsetdef.write;
-
- begin
- ppufile.write_byte(ibsetdef);
- tdef.write;
- writedefref(setof);
- ppufile.write_byte(byte(settype));
- if settype=varset then
- ppufile.write_long(savesize);
- end;
-
- {$ifdef GDB}
- function tsetdef.stabstring : pchar;
-
- begin
- stabstring := strpnew('S'+setof^.numberstring);
- end;
-
- procedure tsetdef.concatstabto(asmlist : paasmoutput);
-
- begin
- if ( not assigned(sym) or sym^.isusedinstab or use_dbx)
- and not isstabwritten then
- begin
- if assigned(setof) then forcestabto(asmlist,setof);
- inherited concatstabto(asmlist);
- end;
- end;
-
- {$endif GDB}
- procedure tsetdef.deref;
-
- begin
- resolvedef(setof);
- end;
-
- {**************************************
- TFORMALDEF
- **************************************}
-
- constructor tformaldef.init;
-
- begin
- inherited init;
- deftype:=formaldef;
- savesize:=4;
- end;
-
- constructor tformaldef.load;
-
- begin
- {$ifdef GDB}
- tdef.load;
- {$endif GDB}
- deftype:=formaldef;
- savesize:=4;
- end;
-
- procedure tformaldef.write;
-
- begin
- ppufile.write_byte(ibformaldef);
- tdef.write;
- end;
-
- {$ifdef GDB}
- function tformaldef.stabstring : pchar;
-
- begin
- stabstring := strpnew('formal'+numberstring+';');
- end;
-
-
- procedure tformaldef.concatstabto(asmlist : paasmoutput);
-
- begin
- { formaldef can't be stab'ed !}
- end;
- {$endif GDB}
-
- {**************************************
- TARRAYDEF
- **************************************}
-
- constructor tarraydef.init(l,h : longint;rd : pdef);
-
- begin
- tdef.init;
- deftype:=arraydef;
- lowrange:=l;
- highrange:=h;
- rangedef:=rd;
- rangenr:=0;
- definition:=nil;
- end;
-
- constructor tarraydef.load;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=arraydef;
- { die Adressen werden spter berechnet }
- definition:=readdefref;
- rangedef:=readdefref;
- lowrange:=readlong;
- highrange:=readlong;
- rangenr:=0;
- end;
-
- procedure tarraydef.genrangecheck;
-
- begin
- if rangenr=0 then
- begin
- { generates the data for range checking }
- getlabelnr(rangenr);
- datasegment^.concat(new(pai_symbol,init('R_'+tostr(rangenr))));
- datasegment^.concat(new(pai_const,init_32bit(lowrange)));
- datasegment^.concat(new(pai_const,init_32bit(highrange)));
- end;
- end;
-
- procedure tarraydef.deref;
-
- begin
- resolvedef(definition);
- resolvedef(rangedef);
- end;
-
- procedure tarraydef.write;
-
- begin
- ppufile.write_byte(ibarraydef);
- tdef.write;
- writedefref(definition);
- writedefref(rangedef);
- ppufile.write_long(lowrange);
- ppufile.write_long(highrange);
- end;
-
- {$ifdef GDB}
- function tarraydef.stabstring : pchar;
- begin
- stabstring := strpnew('ar'+rangedef^.numberstring+';'
- +tostr(lowrange)+';'+tostr(highrange)+';'+definition^.numberstring);
- end;
-
- procedure tarraydef.concatstabto(asmlist : paasmoutput);
-
- begin
- if (not assigned(sym) or sym^.isusedinstab or use_dbx)
- and not isstabwritten then
- begin
- {when array are inserted they have no definition yet !!}
- if assigned(definition) then
- inherited concatstabto(asmlist);
- end;
- end;
-
- {$endif GDB}
- function tarraydef.elesize : longint;
-
- begin
- elesize:=definition^.size;
- end;
-
- function tarraydef.size : longint;
-
- begin
- size:=(highrange-lowrange+1)*elesize;
- end;
-
- {**************************************
- TRECDEF
- **************************************}
-
- constructor trecdef.init(p : psymtable);
-
- begin
- tdef.init;
- deftype:=recorddef;
- symtable:=p;
- savesize:=symtable^.datasize;
- symtable^.defowner := @self;
- end;
-
- constructor trecdef.load;
-
- var
- oldread_member : boolean;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=recorddef;
- savesize:=readlong;
- oldread_member:=read_member;
- read_member:=true;
- symtable:=new(psymtable,loadasstruct(recordsymtable));
- read_member:=oldread_member;
- symtable^.defowner := @self;
- end;
-
- destructor trecdef.done;
-
- begin
- {$ifndef GDB}
- dispose(symtable);
- {$else GDB}
- if assigned(symtable) then dispose(symtable,done);
- inherited done;
- {$endif GDB}
- end;
-
- procedure trecdef.deref;
-
- var
- hp : pdef;
- oldrecsyms : psymtable;
-
- begin
- oldrecsyms:=aktrecordsymtable;
- aktrecordsymtable:=symtable;
- { now dereference the definitions }
- hp:=symtable^.wurzeldef;
- while assigned(hp) do
- begin
- hp^.deref;
-
- { set owner }
- hp^.owner:=symtable;
-
- hp:=hp^.next;
- end;
- {$ifdef tp}
- symtable^.foreach(derefsym);
- {$else}
- symtable^.foreach(@derefsym);
- {$endif}
- aktrecordsymtable:=oldrecsyms;
- end;
-
- procedure trecdef.write;
-
- var
- oldread_member : boolean;
-
- begin
- oldread_member:=read_member;
- read_member:=true;
- ppufile.write_byte(ibrecorddef);
- tdef.write;
- ppufile.write_long(savesize);
- self.symtable^.writeasstruct;
- read_member:=oldread_member;
- end;
-
- {$ifdef GDB}
-
- Const StabRecString : pchar = Nil;
- StabRecSize : longint = 0;
- RecOffset : Longint = 0;
-
- procedure addname(p : psym);
-
- var news, newrec : pchar;
- begin
- { static variables from objects are like global objects }
- if ((p^.properties and sp_static)<>0) then
- exit;
- If p^.typ = varsym then
- begin
- newrec := strpnew(p^.name+':'+pvarsym(p)^.definition^.numberstring
- +','+tostr(pvarsym(p)^.address*8)+','
- +tostr(pvarsym(p)^.definition^.size*8)+';');
- if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
- begin
- getmem(news,stabrecsize+memsizeinc);
- strcopy(news,stabrecstring);
- freemem(stabrecstring,stabrecsize);
- stabrecsize:=stabrecsize+memsizeinc;
- stabrecstring:=news;
- end;
- strcat(StabRecstring,newrec);
- strdispose(newrec);
- {This should be used for case !!}
- RecOffset := RecOffset + pvarsym(p)^.definition^.size;
- end;
- end;
-
- function trecdef.stabstring : pchar;
- Var oldrec : pchar;
- oldsize : longint;
-
-
- begin
- oldrec := stabrecstring;
- oldsize:=stabrecsize;
- GetMem(stabrecstring,memsizeinc);
- stabrecsize:=memsizeinc;
- strpcopy(stabRecString,'s'+tostr(savesize));
- RecOffset := 0;
- {$ifdef tp}
- symtable^.foreach(addname);
- {$else}
- symtable^.foreach(@addname);
- {$endif}
- { FPC doesn't want to convert a char to a pchar}
- { is this a bug ? }
- strpcopy(strend(StabRecString),';');
- stabstring := strnew(StabRecString);
- Freemem(stabrecstring,stabrecsize);
- stabrecstring := oldrec;
- stabrecsize:=oldsize;
- end;
-
- procedure trecdef.concatstabto(asmlist : paasmoutput);
-
- begin
- if ( not assigned(sym) or sym^.isusedinstab or use_dbx)
- and not isstabwritten then
- begin
- inherited concatstabto(asmlist);
- end;
- end;
-
- {$endif GDB}
-
- {**************************************
- TABSTRACTPROCDEF
- **************************************}
-
- constructor tabstractprocdef.init;
-
- begin
- inherited init;
- para1:=nil;
- options:=0;
- retdef:=voiddef;
- savesize:=4;
- end;
-
- destructor tabstractprocdef.done;
-
- var
- hp : pdefcoll;
-
- begin
- hp:=para1;
- while assigned(hp) do
- begin
- para1:=hp^.next;
- dispose(hp);
- hp:=para1;
- end;
- inherited done;
- end;
-
- procedure tabstractprocdef.concatdef(p : pdef;vsp : tvarspez);
-
- var
- hp : pdefcoll;
-
- begin
- new(hp);
- hp^.paratyp:=vsp;
- hp^.data:=p;
- hp^.next:=para1;
- para1:=hp;
- end;
-
- procedure tabstractprocdef.deref;
-
- var
- hp : pdefcoll;
-
- begin
- inherited deref;
- resolvedef(retdef);
- hp:=para1;
- while assigned(hp) do
- begin
- resolvedef(hp^.data);
- hp:=hp^.next;
- end;
- end;
-
- constructor tabstractprocdef.load;
-
- var
- last,hp : pdefcoll;
- count,i : word;
-
- begin
- {$ifdef GDB}
- tdef.load;
- {$endif GDB}
- retdef:=readdefref;
- options:=readlong;
- count:=readword;
- para1:=nil;
- savesize:=4;
- for i:=1 to count do
- begin
- new(hp);
- hp^.paratyp:=tvarspez(readbyte);
- hp^.data:=readdefref;
- hp^.next:=nil;
- if para1=nil then
- para1:=hp
- else
- last^.next:=hp;
- last:=hp;
- end;
- end;
-
- procedure tabstractprocdef.write;
-
- var
- count : word;
- hp : pdefcoll;
-
- begin
- tdef.write;
- writedefref(retdef);
- ppufile.write_long(options);
- hp:=para1;
- count:=0;
- while assigned(hp) do
- begin
- inc(count);
- hp:=hp^.next;
- end;
- ppufile.write_word(count);
- hp:=para1;
- while assigned(hp) do
- begin
- ppufile.write_byte(byte(hp^.paratyp));
- writedefref(hp^.data);
- hp:=hp^.next;
- end;
- end;
-
- {$ifdef GDB}
- function tabstractprocdef.stabstring : pchar;
- begin
- stabstring := strpnew('abstractproc'+numberstring+';');
- end;
-
- procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
-
- begin
- if (not assigned(sym) or sym^.isusedinstab or use_dbx)
- and not isstabwritten then
- begin
- {if assigned(retdef) then forcestabto(asmlist,retdef);}
- inherited concatstabto(asmlist);
- end;
- end;
-
- {$endif GDB}
-
- {**************************************
- TPROCDEF
- **************************************}
-
- constructor tprocdef.init;
-
- begin
- inherited init;
- deftype:=procdef;
- _mangledname:=nil;
- nextoverloaded:=nil;
- extnumber:=-1;
- {$ifndef GDB}
- parast:=new(psymtable,init(parasymtable));
- {$endif * not GDB *}
- localst:=new(psymtable,init(localsymtable));
- {$ifdef GDB}
- parast:=new(psymtable,init(parasymtable));
- {$endif GDB}
-
- {$ifdef UseBrowser}
- defref:=nil;
- add_new_ref(defref);
- lastref:=defref;
- lastwritten:=nil;
- refcount:=1;
- {$endif UseBrowser}
-
- { first, we assume, that all registers are used }
- {$ifdef i386}
- usedregisters:=$ff;
- {$endif i386}
- {$ifdef m68k}
- usedregisters:=$FFFF;
- {$endif}
- {$ifdef alpha}
- usedregisters_int:=$ffffffff;
- usedregisters_fpu:=$ffffffff;
- {$endif alpha}
- forwarddef:=true;
- _class := nil;
- end;
-
- constructor tprocdef.load;
-
- var
- s : string;
-
- begin
- deftype:=procdef;
- inherited load;
- {$ifdef i386}
- usedregisters:=readbyte;
- {$endif i386}
- {$ifdef m68k}
- usedregisters:=readword;
- {$endif}
- {$ifdef alpha}
- usedregisters_int:=readlong;
- usedregisters_fpu:=readlong;
- {$endif alpha}
-
- s:=readstring;
- setstring(_mangledname,s);
-
- extnumber:=readlong;
- nextoverloaded:=pprocdef(readdefref);
- { this $ifdef GDB made the ppu files different !! }
- _class := pobjectdef(readdefref);
-
- if gendeffile and ((options and poexports)<>0) then
- writeln(deffile,#9+mangledname);
-
- parast:=nil;
- localst:=nil;
- forwarddef:=false;
- {$ifdef UseBrowser}
- if (current_module^.flags and uf_uses_browser)<>0 then
- load_references
- else
- begin
- lastref:=nil;
- lastwritten:=nil;
- defref:=nil;
- refcount:=0;
- end;
- {$endif UseBrowser}
- end;
-
- {$ifdef UseBrowser}
- procedure tprocdef.load_references;
-
- var fileindex : word;
- b : byte;
- l : longint;
-
- begin
- b:=readbyte;
- refcount:=0;
- lastref:=nil;
- lastwritten:=nil;
- defref:=nil;
- while b=ibref do
- begin
- fileindex:=readword;
- l:=readlong;
- inc(refcount);
- lastref:=new(pref,load(lastref,fileindex,l));
- if refcount=1 then defref:=lastref;
- b:=readbyte;
- end;
- if b <> ibend then
- Message(unit_f_ppu_read);
- end;
-
- procedure tprocdef.write_references;
-
- var ref : pref;
-
- begin
- { references do not change the ppu caracteristics }
- { this only save the references to variables/functions }
- { defined in the unit what about the others }
- ppufile.do_crc:=false;
- if assigned(lastwritten) then
- ref:=lastwritten
- else
- ref:=defref;
- while assigned(ref) do
- begin
- writebyte(ibref);
- writeword(ref^.inputfile^.ref_index);
- writelong(ref^.lineno);
- ref:=ref^.nextref;
- end;
- lastwritten:=lastref;
- writebyte(ibend);
- ppufile.do_crc:=true;
- end;
-
- procedure tprocdef.write_external_references;
-
- var ref : pref;
-
- begin
- ppufile.do_crc:=false;
- if lastwritten=lastref then exit;
- writebyte(ibextdefref);
- writedefref(@self);
- if assigned(lastwritten) then
- ref:=lastwritten
- else
- ref:=defref;
- while assigned(ref) do
- begin
- writebyte(ibref);
- writeword(ref^.inputfile^.ref_index);
- writelong(ref^.lineno);
- ref:=ref^.nextref;
- end;
- lastwritten:=lastref;
- writebyte(ibend);
- ppufile.do_crc:=true;
- end;
-
- procedure tprocdef.write_ref_to_file(var f : text);
-
- var ref : pref;
-
- begin
- ref:=defref;
- while assigned(ref) do
- begin
- writeln(f,ref^.get_file_line);
- ref:=ref^.nextref;
- end;
- end;
- {$endif UseBrowser}
-
- destructor tprocdef.done;
-
- begin
- if assigned(parast) then
- dispose(parast,done);
- if assigned(localst) then
- dispose(localst,done);
- if
- {$ifdef tp}
- not(use_big) and
- {$endif}
- assigned(_mangledname) then
- strdispose(_mangledname);
- inherited done;
- end;
-
- procedure tprocdef.write;
-
- begin
- ppufile.write_byte(ibprocdef);
- inherited write;
- {$ifdef i386}
- ppufile.write_byte(usedregisters);
- {$endif i386}
- {$ifdef m68k}
- ppufile.write_word(usedregisters);
- {$endif}
-
- {$ifdef alpha}
- ppufile.write_long(usedregisters_int);
- ppufile.write_long(usedregisters_fpu);
- {$endif alpha}
-
- writestring(mangledname);
- ppufile.write_long(extnumber);
- writedefref(nextoverloaded);
- writedefref(_class);
- {$ifdef UseBrowser}
- if (current_module^.flags and uf_uses_browser)<>0 then
- write_references;
- {$endif UseBrowser}
- end;
-
- {$ifdef GDB}
- procedure addparaname(p : psym);
- var vs : char;
-
- begin
- if pvarsym(p)^.varspez = vs_value then vs := '1'
- else vs := '0';
- strpcopy(strend(StabRecString),p^.name+':'+pvarsym(p)^.definition^.numberstring+','+vs+';');
- end;
-
- function tprocdef.stabstring : pchar;
- var param : pdefcoll;
- i : word;
- vartyp : char;
- oldrec : pchar;
- begin
- oldrec := stabrecstring;
- getmem(StabRecString,1024);
- param := para1;
- i := 0;
- while assigned(param) do
- begin
- inc(i);
- param := param^.next;
- end;
- strpcopy(StabRecString,'f'+retdef^.numberstring);
- if i>0 then
- begin
- strpcopy(strend(StabRecString),','+tostr(i)+';');
- if assigned(parast) then
- {$IfDef TP}
- parast^.foreach(addparaname)
- {$Else}
- parast^.foreach(@addparaname)
- {$EndIf}
- else
- begin
- param := para1;
- i := 0;
- while assigned(param) do
- begin
- inc(i);
- if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
- {Here we have lost the parameter names !!}
- {using lower case parameters }
- strpcopy(strend(stabrecstring),'p'+tostr(i)
- +':'+param^.data^.numberstring+','+vartyp+';');
- param := param^.next;
- end;
- end;
- {strpcopy(strend(StabRecString),';');}
- end;
- stabstring := strnew(stabrecstring);
- freemem(stabrecstring,1024);
- stabrecstring := oldrec;
- end;
-
- procedure tprocdef.concatstabto(asmlist : paasmoutput);
-
- begin
- end;
- {$endif GDB}
-
- procedure tprocdef.deref;
-
- begin
- inherited deref;
- resolvedef(pdef(nextoverloaded));
- resolvedef(pdef(_class));
- end;
-
- function tprocdef.mangledname : string;
-
- {$ifdef tp}
- var
- oldpos : longint;
- s : string;
- b : byte;
- {$endif tp}
-
- begin
- {$ifdef tp}
- if use_big then
- begin
- symbolstream.seek(longint(_mangledname));
- symbolstream.read(b,1);
- symbolstream.read(s[1],b);
- s[0]:=chr(b);
- mangledname:=s;
- end
- else
- {$endif}
- begin
- mangledname:=strpas(_mangledname);
- end;
- end;
-
- {$IfDef GDB}
- function tprocdef.cplusplusmangledname : string;
-
- var
- s,s2 : string;
- param : pdefcoll;
-
- begin
- s := sym^.name;
- if _class <> nil then
- begin
- s2 := _class^.name^;
- s := s+'__'+tostr(length(s2))+s2;
- end else s := s + '_';
- param := para1;
- while assigned(param) do
- begin
- s2 := param^.data^.sym^.name;
- s := s+tostr(length(s2))+s2;
- param := param^.next;
- end;
- cplusplusmangledname:=s;
- end;
- {$EndIf GDB}
-
- procedure tprocdef.setmangledname(const s : string);
-
- begin
- if
- {$ifdef tp}
- not(use_big) and
- {$endif}
- (assigned(_mangledname)) then
- strdispose(_mangledname);
- setstring(_mangledname,s);
- end;
-
- {**************************************
- TPROCVARDEF
- **************************************}
-
- constructor tprocvardef.init;
-
- begin
- inherited init;
- deftype:=procvardef;
- end;
-
- constructor tprocvardef.load;
-
- begin
- {$ifndef GDB}
- deftype:=procvardef;
- {$endif * not GDB *}
- inherited load;
- {$ifdef GDB}
- deftype:=procvardef;
- set_globalnb;
- {$endif GDB}
- end;
-
- procedure tprocvardef.write;
-
- begin
- ppufile.write_byte(ibprocvardef);
- inherited write;
- end;
-
- {$ifdef GDB}
- function tprocvardef.stabstring : pchar;
-
- var
- nss : pchar;
- i : word;
- vartyp : char;
- pst : pchar;
- param : pdefcoll;
-
- begin
- i := 0;
- param := para1;
- while assigned(param) do
- begin
- inc(i);
- param := param^.next;
- end;
- getmem(nss,1024);
- strpcopy(nss,'f'+retdef^.numberstring+','+tostr(i)+';');
- param := para1;
- i := 0;
- while assigned(param) do
- begin
- inc(i);
- if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
- {Here we have lost the parameter names !!}
- pst := strpnew('p'+tostr(i)+':'+param^.data^.numberstring+','+vartyp+';');
- strcat(nss,pst);
- strdispose(pst);
- param := param^.next;
- end;
- {strpcopy(strend(nss),';');}
- stabstring := strnew(nss);
- freemem(nss,1024);
- end;
-
- procedure tprocvardef.concatstabto(asmlist : paasmoutput);
-
- begin
- if ( not assigned(sym) or sym^.isusedinstab or use_dbx)
- and not isstabwritten then
- inherited concatstabto(asmlist);
- isstabwritten:=true;
- end;
- {$endif GDB}
-
- {**************************************
- TOBJECTDEF
- **************************************}
-
- {$ifdef GDB}
- const
- vtabletype : word = 0;
- vtableassigned : boolean = false;
-
- {$endif GDB}
- constructor tobjectdef.init(const n : string;c : pobjectdef);
-
- begin
- tdef.init;
- deftype:=objectdef;
- childof:=c;
- options:=0;
- { privatesyms:=new(psymtable,init(objectsymtable));
- protectedsyms:=new(psymtable,init(objectsymtable)); }
- publicsyms:=new(psymtable,init(objectsymtable));
- publicsyms^.name := stringdup(n);
- { add the data of the anchestor class }
- if assigned(childof) then
- begin
- publicsyms^.datasize:=
- publicsyms^.datasize-4+childof^.publicsyms^.datasize;
- end;
- name:=stringdup(n);
- savesize := publicsyms^.datasize;
- publicsyms^.defowner:=@self;
- end;
-
- constructor tobjectdef.load;
-
- var
- oldread_member : boolean;
-
- begin
- {$ifdef GDB}
- tdef.load;
- set_globalnb;
- {$endif GDB}
- deftype:=objectdef;
- savesize:=readlong;
- name:=stringdup(readstring);
-
- childof:=pobjectdef(readdefref);
- options:=readlong;
- oldread_member:=read_member;
- read_member:=true;
- if (options and (oo_hasprivate or oo_hasprotected))<>0 then
- object_options:=true;
- publicsyms:=new(psymtable,loadasstruct(objectsymtable));
- object_options:=false;
- publicsyms^.defowner:=@self;
- publicsyms^.datasize:=savesize;
- {$ifdef GDB}
- publicsyms^.name := stringdup(name^);
- {$endif GDB}
- read_member:=oldread_member;
-
- { handles the predefined class tobject }
- { the last TOBJECT which is loaded gets }
- { it ! }
- if (name^='TOBJECT') and not(cs_compilesystem in aktswitches) and
- isclass and (childof=pointer($ffffffff)) then
- class_tobject:=@self;
- end;
-
- procedure tobjectdef.check_forwards;
-
- begin
- publicsyms^.check_forwards;
- if (options and oo_isforward)<>0 then
- begin
- { ok, in future, the forward can be resolved }
- Message1(sym_e_class_forward_not_resolved,name^);
- options:=options and not(oo_isforward);
- end;
- end;
-
- destructor tobjectdef.done;
-
- begin
- {!!!!
- if assigned(privatesyms) then
- dispose(privatesyms,done);
- if assigned(protectedsyms) then
- dispose(protectedsyms,done); }
- if assigned(publicsyms) then
- dispose(publicsyms,done);
- if (options and oo_isforward)<>0 then
- Message1(sym_e_class_forward_not_resolved,name^);
- stringdispose(name);
- tdef.done;
- end;
-
- { true, if self inherits from d (or if they are equal) }
- function tobjectdef.isrelated(d : pobjectdef) : boolean;
-
- var
- hp : pobjectdef;
-
- begin
- hp:=@self;
- while assigned(hp) do
- begin
- if hp=d then
- begin
- isrelated:=true;
- exit;
- end;
- hp:=hp^.childof;
- end;
- isrelated:=false;
- end;
-
- function tobjectdef.size : longint;
-
- begin
- if (options and oois_class)<>0 then
- size:=4
- else
- size:=publicsyms^.datasize;
- end;
-
- procedure tobjectdef.deref;
-
- var
- hp : pdef;
- oldrecsyms : psymtable;
-
- begin
- resolvedef(pdef(childof));
- oldrecsyms:=aktrecordsymtable;
- aktrecordsymtable:=publicsyms;
- { nun die Definitionen dereferenzieren }
- hp:=publicsyms^.wurzeldef;
- while assigned(hp) do
- begin
- hp^.deref;
-
- {Besitzer setzen }
- hp^.owner:=publicsyms;
-
- hp:=hp^.next;
- end;
- {$ifdef tp}
- publicsyms^.foreach(derefsym);
- {$else}
- publicsyms^.foreach(@derefsym);
- {$endif}
- aktrecordsymtable:=oldrecsyms;
- end;
-
- function tobjectdef.vmt_mangledname : string;
-
- {DM: I get a nil pointer on the owner name. I don't know if this
- mayhappen, and I have therefore fixed the problem by doing nil pointer
- checks.}
-
- var s1,s2:string;
-
- begin
- if owner^.name=nil then
- s1:=''
- else
- s1:=owner^.name^;
- if name=nil then
- s2:=''
- else
- s2:=name^;
- vmt_mangledname:='VMT_'+s1+'$_'+s2;
- end;
-
- function tobjectdef.isclass : boolean;
-
- begin
- isclass:=(options and oois_class)<>0;
- end;
-
- procedure tobjectdef.write;
-
- var
- oldread_member : boolean;
-
- begin
- oldread_member:=read_member;
- read_member:=true;
- ppufile.write_byte(ibobjectdef);
- tdef.write;
- ppufile.write_long(size);
- writestring(name^);
- writedefref(childof);
- ppufile.write_long(options);
- if (options and (oo_hasprivate or oo_hasprotected))<>0 then
- object_options:=true;
- publicsyms^.writeasstruct;
- object_options:=false;
- read_member:=oldread_member;
- end;
-
- {$ifdef GDB}
- procedure addprocname(p :psym);
- var virtualind,argnames : string;
- news, newrec : pchar;
- pd,ipd : pprocdef;
- lindex : longint;
- para : pdefcoll;
- arglength : byte;
- begin
- If p^.typ = procsym then
- begin
- pd := pprocsym(p)^.definition;
- { this will be used for full implementation of object stabs
- not yet done }
- ipd := pd;
- while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
- if (pd^.options and povirtualmethod) <> 0 then
- begin
- lindex := pd^.extnumber;
- {doesnt seem to be necessary
- lindex := lindex or $80000000;}
- virtualind := '*'+tostr(lindex)+';'+ipd^._class^.numberstring+';'
- end else virtualind := '.';
- { arguments are not listed here }
- {we don't need another definition}
- para := pd^.para1;
- argnames := '';
- while assigned(para) do
- begin
- if para^.data^.deftype = formaldef then
- argnames := argnames+'3var'
- else
- begin
- { if the arg definition is like (v: ^byte;..
- there is no sym attached to data !!! }
- if assigned(para^.data^.sym) then
- begin
- arglength := length(para^.data^.sym^.name);
- argnames := argnames + tostr(arglength)+para^.data^.sym^.name;
- end
- else
- begin
- argnames:=argnames+'11unnamedtype';
- end;
- end;
- para := para^.next;
- end;
- ipd^.isstabwritten := true;
- { here 2A must be changed for private and protected }
- newrec := strpnew(p^.name+'::'+ipd^.numberstring
- +'=##'+pd^.retdef^.numberstring+';:'+argnames+';2A'
- +virtualind+';');
- { get spare place for a string at the end }
- if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
- begin
- getmem(news,stabrecsize+memsizeinc);
- strcopy(news,stabrecstring);
- freemem(stabrecstring,stabrecsize);
- stabrecsize:=stabrecsize+memsizeinc;
- stabrecstring:=news;
- end;
- strcat(StabRecstring,newrec);
- {freemem(newrec,memsizeinc); }
- strdispose(newrec);
- {This should be used for case !!}
- RecOffset := RecOffset + pd^.size;
- end;
- end;
-
- function tobjectdef.stabstring : pchar;
- var anc : pobjectdef;
- oldrec : pchar;
- oldrecsize : longint;
- str_end : string;
- begin
- oldrec := stabrecstring;
- oldrecsize:=stabrecsize;
- stabrecsize:=memsizeinc;
- GetMem(stabrecstring,stabrecsize);
- strpcopy(stabRecString,'s'+tostr(size));
- if assigned(childof) then
- {only one ancestor not virtual, public, at base offset 0 }
- { !1 , 0 2 0 , }
- strpcopy(strend(stabrecstring),'!1,020,'+childof^.numberstring+';');
- {virtual table to implement yet}
- RecOffset := 0;
- {$ifdef tp}
- publicsyms^.foreach(addname);
- {$else}
- publicsyms^.foreach(@addname);
- {$endif tp}
- if (options and oo_hasvirtual) <> 0 then
- if not assigned(childof) or ((childof^.options and oo_hasvirtual) = 0) then
- begin
- str_end:='$vf'+numberstring+':'+typeglobalnumber('vtblarray')+',0;';
- strpcopy(strend(stabrecstring),'$vf'+numberstring+':'+typeglobalnumber('vtblarray')+',0;');
- end;
- {$ifdef tp}
- publicsyms^.foreach(addprocname);
- {$else}
- publicsyms^.foreach(@addprocname);
- {$endif tp }
- if (options and oo_hasvirtual) <> 0 then
- begin
- anc := @self;
- while assigned(anc^.childof) and ((anc^.childof^.options and oo_hasvirtual) <> 0) do
- anc := anc^.childof;
- str_end:=';~%'+anc^.numberstring+';';
- end
- else
- str_end:=';';
- strpcopy(strend(stabrecstring),str_end);
- stabstring := strnew(StabRecString);
- freemem(stabrecstring,stabrecsize);
- stabrecstring := oldrec;
- stabrecsize:=oldrecsize;
- end;
-
- {$endif GDB}
-
- {**************************************
- TERRORDEF
- **************************************}
-
- constructor terrordef.init;
-
- begin
- tdef.init;
- deftype:=errordef;
- end;
-
- {$ifdef GDB}
- function terrordef.stabstring : pchar;
-
- begin
- stabstring:=strpnew('error'+numberstring);
- end;
-
- {$endif GDB}
-
- { type helper routines for objects }
- function search_class_member(pd : pobjectdef;const n : string) : psym;
-
- var
- sym : psym;
-
- begin
- sym:=nil;
- while assigned(pd) do
- begin
- sym:=pd^.publicsyms^.search(n);
- if assigned(sym) then
- break;
- pd:=pd^.childof;
- end;
- search_class_member:=sym;
- end;
-
- var
- _defaultprop : ppropertysym;
-
- procedure testfordefaultproperty(p : psym);
-
- begin
- if (p^.typ=propertysym) and ((ppropertysym(p)^.options and ppo_defaultproperty)<>0) then
- _defaultprop:=ppropertysym(p);
- end;
-
- function search_default_property(pd : pobjectdef) : ppropertysym;
-
- begin
- _defaultprop:=nil;
- while assigned(pd) do
- begin
- {$ifdef tp}
- pd^.publicsyms^.foreach(testfordefaultproperty);
- {$else}
- pd^.publicsyms^.foreach(@testfordefaultproperty);
- {$endif}
- if assigned(_defaultprop) then
- break;
- pd:=pd^.childof;
- end;
- search_default_property:=_defaultprop;
- end;
-
- procedure init_symtable;
-
- begin
- registerdef:=false;
- read_member:=false;
- generrorsym:=new(perrorsym,init);
- swurzel:=nil;
- { readunit_lastloaded:=nil; }
- {$ifdef GDB}
- firstglobaldef:=nil;
- lastglobaldef:=nil;
- {$endif GDB}
- commandlinedefines.init;
- globaltypecount:=1;
- pglobaltypecount:=@globaltypecount;
- end;
-
- procedure reset_gdb_info;
- var def : pdef;
- begin
- {$ifdef GDB }
- def:=firstglobaldef;
- GlobalTypeCount:=1;
- pglobaltypecount:=@globaltypecount;
- while assigned(def) do
- begin
- if assigned(def^.sym) then
- begin
- { was a check
-
- write('Type: ',longint(def^.deftype));
- if def^.deftype=procdef then
- write(' mangle name: ',pprocdef(def)^.mangledname);
- }
- if def^.sym^.typ=typesym then
- def^.sym^.isusedinstab:=false;
- {
- writeln(' Name: ',def^.sym^.name);
- }
- end;
- def^.isstabwritten:=false;
- def^.globalnb:=0;
- if (def^.deftype=orddef) then
- porddef(def)^.rangenr:=0;
- if (def^.deftype=arraydef) then
- parraydef(def)^.rangenr:=0;
- def:=def^.nextglobal;
- end;
- {$endif GDB }
- end;
-
- procedure done_symtable;
-
- begin
- dispose(generrorsym,done);
- dispose_global:=true;
- while assigned(symtablestack) do dellexlevel;
- {$ifndef GDB}
- dispose(generrordef,done);
- dispose(s32bitdef,done);
- dispose(u32bitdef,done);
- dispose(cstringdef,done);
- {$ifdef UseLongString}
- dispose(clongstringdef,done);
- {$endif UseLongString}
- {$ifdef UseAnsiString}
- dispose(cansistringdef,done);
- {$endif UseAnsiString}
- dispose(cchardef,done);
- {dispose(cs64realdef,done);}
- {dispose(voiddef,done); belongs to system !}
- dispose(u8bitdef,done);
- dispose(u16bitdef,done);
- dispose(booldef,done);
- dispose(voidpointerdef,done);
- dispose(cfiledef,done);
- {$endif GDB}
- commandlinedefines.done;
- end;
-
- var
- i : ttoken;
- begin
- { no operator is overloaded }
- for i:=PLUS to last_overloaded do
- overloaded_operators[i]:=nil;
- end.
- {
- $Log: symtable.pas,v $
- Revision 1.1.1.1.2.4 1998/08/13 17:41:28 florian
- + some stuff for the PalmOS added
-
- Revision 1.1.1.1.2.3 1998/08/13 13:26:04 carl
- + support for Big endian reading of units
-
- Revision 1.1.1.1.2.2 1998/05/21 12:22:12 carl
- * bugfix of handle sizes for m68k systems
-
- Revision 1.1.1.1.2.1 1998/04/08 11:38:44 peter
- * nasm patches, pierres symtable patch
-
- Revision 1.1.1.1 1998/03/25 11:18:15 root
- * Restored version
-
- Revision 1.49 1998/03/24 21:48:36 florian
- * just a couple of fixes applied:
- - problem with fixed16 solved
- - internalerror 10005 problem fixed
- - patch for assembler reading
- - small optimizer fix
- - mem is now supported
-
- Revision 1.48 1998/03/21 23:59:39 florian
- * indexed properties fixed
- * ppu i/o of properties fixed
- * field can be also used for write access
- * overriding of properties
-
- Revision 1.47 1998/03/10 16:27:45 pierre
- * better line info in stabs debug
- * symtabletype and lexlevel separated into two fields of tsymtable
- + ifdef MAKELIB for direct library output, not complete
- + ifdef CHAINPROCSYMS for overloaded seach across units, not fully
- working
- + ifdef TESTFUNCRET for setting func result in underfunction, not
- working
-
- Revision 1.46 1998/03/10 01:17:28 peter
- * all files have the same header
- * messages are fully implemented, EXTDEBUG uses Comment()
- + AG... files for the Assembler generation
-
- Revision 1.45 1998/03/06 00:52:56 peter
- * replaced all old messages from errore.msg, only ExtDebug and some
- Comment() calls are left
- * fixed options.pas
-
- Revision 1.44 1998/03/04 17:34:09 michael
- + Changed ifdef FPK to ifdef FPC
-
- Revision 1.43 1998/03/04 01:35:12 peter
- * messages for unit-handling and assembler/linker
- * the compiler compiles without -dGDB, but doesn't work yet
- + -vh for Hint
-
- Revision 1.42 1998/03/03 23:18:49 florian
- * ret $8 problem with unit init/main program fixed
-
- Revision 1.41 1998/03/02 01:49:30 peter
- * renamed target_DOS to target_GO32V1
- + new verbose system, merged old errors and verbose units into one new
- verbose.pas, so errors.pas is obsolete
-
- Revision 1.40 1998/03/01 22:46:22 florian
- + some win95 linking stuff
- * a couple of bugs fixed:
- bug0055,bug0058,bug0059,bug0064,bug0072,bug0093,bug0095,bug0098
-
- Revision 1.39 1998/02/27 21:24:15 florian
- * dll support changed (dll name can be also a string contants)
-
- Revision 1.38 1998/02/27 09:26:10 daniel
- * Changed symtable handling so no junk symtable is put on the symtablestack.
-
- Revision 1.37 1998/02/24 15:36:27 daniel
- + Added owner:=nil to Tsym.init. Caused problems with TP compiling.
-
- Revision 1.36 1998/02/24 14:20:58 peter
- + tstringcontainer.empty
- * ld -T option restored for linux
- * libraries are placed before the objectfiles in a .PPU file
- * removed 'uses link' from files.pas
-
- Revision 1.35 1998/02/22 23:03:36 peter
- * renamed msource->mainsource and name->unitname
- * optimized filename handling, filename is not seperate anymore with
- path+name+ext, this saves stackspace and a lot of fsplit()'s
- * recompiling of some units in libraries fixed
- * shared libraries are working again
- + $LINKLIB <lib> to support automatic linking to libraries
- + libraries are saved/read from the ppufile, also allows more libraries
- per ppufile
-
- Revision 1.34 1998/02/17 21:21:01 peter
- + Script unit
- + __EXIT is called again to exit a program
- - target_info.link/assembler calls
- * linking works again for dos
- * optimized a few filehandling functions
- * fixed stabs generation for procedures
-
- Revision 1.33 1998/02/16 12:51:50 michael
- + Implemented linker object
-
- Revision 1.32 1998/02/14 01:45:32 peter
- * more fixes
- - pmode target is removed
- - search_as_ld is removed, this is done in the link.pas/assemble.pas
- + findexe() to search for an executable (linker,assembler,binder)
-
- Revision 1.31 1998/02/13 22:26:40 peter
- * fixed a few SigSegv's
- * INIT$$ was not written for linux!
- * assembling and linking works again for linux and dos
- + assembler object, only attasmi3 supported yet
- * restore pp.pas with AddPath etc.
-
- Revision 1.30 1998/02/13 10:35:47 daniel
- * Made Motorola version compilable.
- * Fixed optimizer
-
- Revision 1.29 1998/02/12 17:19:28 florian
- * fixed to get remake3 work, but needs additional fixes (output, I don't like
- also that aktswitches isn't a pointer)
-
- Revision 1.28 1998/02/12 11:50:47 daniel
- Yes! Finally! After three retries, my patch!
-
- Changes:
-
- Complete rewrite of psub.pas.
- Added support for DLL's.
- Compiler requires less memory.
- Platform units for each platform.
-
- Revision 1.27 1998/02/07 23:05:06 florian
- * once more MMX
-
- Revision 1.26 1998/02/07 06:49:14 carl
- * small fixes to make it compile with non-386 targets
-
- Revision 1.25 1998/02/06 23:08:34 florian
- + endian to targetinfo and sourceinfo added
- + endian independed writing of ppu file (reading missed), a PPU file
- is written with the target endian
-
- Revision 1.24 1998/02/06 10:34:29 florian
- * bug0082 and bug0084 fixed
-
- Revision 1.23 1998/02/03 22:13:36 florian
- * clean up
-
- Revision 1.22 1998/02/02 23:39:58 florian
- * forward classes are now allowed without resolving (see sysutils)
-
- Revision 1.21 1998/02/02 00:55:35 peter
- * defdatei -> deffile and some german comments to english
- * search() accepts : as seperater under linux
- * search for ppc.cfg doesn't open a file (and let it open)
- * reorganize the reading of parameters/file a bit
- * all the PPC_ environments are now for all platforms
-
- Revision 1.20 1998/02/01 15:03:01 florian
- * small improvement of tobjectdef.isrelated
-
- Revision 1.19 1998/01/30 17:31:27 pierre
- * bug of cyclic symtablestack fixed
-
- Revision 1.18 1998/01/27 22:02:35 florian
- * small bug fix to the compiler work, I forgot a not(...):(
-
- Revision 1.17 1998/01/25 22:29:05 florian
- * a lot bug fixes on the DOM
-
- Revision 1.16 1998/01/23 17:12:21 pierre
- * added some improvements for as and ld :
- - doserror and dosexitcode treated separately
- - PATH searched if doserror=2
- + start of long and ansi string (far from complete)
- in conditionnal UseLongString and UseAnsiString
- * options.pas cleaned (some variables shifted to globals)gl
-
- Revision 1.15 1998/01/21 21:29:57 florian
- * some fixes for Delphi classes
-
- Revision 1.14 1998/01/16 18:03:19 florian
- * small bug fixes, some stuff of delphi styled constructores added
-
- Revision 1.13 1998/01/16 11:24:28 florian
- + problem with absolute syms in unit files solved
-
- Revision 1.12 1998/01/16 10:33:18 florian
- * bug0077 fixed (problem when reading absolute syms from a unit file)
-
- Revision 1.11 1998/01/13 23:04:17 florian
- * the options member of procdefs, objectdefs and propertysyms is
- noew longint => unit format changed
-
- Revision 1.10 1998/01/13 17:13:10 michael
- * File time handling and file searching is now done in an OS-independent way,
- using the new file treating functions in globals.pas.
-
- Revision 1.9 1998/01/11 04:15:34 carl
- * alignment problem fix for m68k
-
- Revision 1.8 1998/01/10 11:10:42 florian
- + procedure flag poclassmethod for class methods
-
- Revision 1.7 1998/01/09 23:08:36 florian
- + C++/Delphi styled //-comments
- * some bugs in Delphi object model fixed
- + override directive
-
- Revision 1.6 1998/01/09 13:18:13 florian
- + "forward" class declarations (type tclass = class; )
-
- Revision 1.5 1998/01/07 00:17:06 michael
- Restored released version (plus fixes) as current
-
- Revision 1.3 1997/12/09 14:10:52 carl
- + merged both m68k and intel float types
-
- Revision 1.2 1997/12/03 13:57:45 carl
- + writexxx and readxxx now use sizeof(xxxx)
- (except for sets).
-
- Revision 1.1.1.1 1997/11/27 08:33:02 michael
- FPC Compiler CVS start
-
-
- Pre-CVS log:
-
-
- CEC Carl-Eric Codere
- FK Florian Klaempfl
- PM Pierre Muller
- + feature added
- - removed
- * bug fixed or changed
-
- History (started with version 0.9.0):
- 7th december 1996
- * the call offset is now saved in call_offset and not in name (FK)
- 26th december 1996
- + new PPU file handling (FK)
- 26th february 1997
- + fixed comma numbers (FK)
- 5th september 1997
- * fixed a little missing i386
- define for s64bit on line: 3609 (CEC)
- + works with m68k unit (CEC)
- 17th september 1997
- * type t=^b; b=byte;
- works now (FK)
- 25th september 1997:
- + getsize handles now open arrays (FK)
- 1th october 1997
- + adding assignment to overloadable operators (PM)
- 3rd october 1997:
- + created one tfloattype for m68k. Find all ifdef m68k and
- tfloatdef methods modified also (CEC)
- 4th october 1997:
- + added has_jump in enumdef for use in in_succ_x and in_pred_x (PM)
- 13th october 1997:
- + added static modifier for objects variable and methods (PM)
- 25th october 1997:
- + small sets released (FK)
- 19th november 1997:
- + tfiledef.setsize for win32 (FK)
- 20th november 1997:
- + added argconvtyp to tdefcoll (PM)
- }
-
-